如何连接SQL表并返回匹配两个可能值的值?

huangapple go评论68阅读模式
英文:

How to join SQL tables and return values that match two possible values?

问题

我有两个表。

pos.transaction:

  • Id(主键)
  • MainframeTransactionSequenceNumber(字符串)
  • TransactionNumber(字符串)

pos.payment:

  • Id(主键)
  • TransactionId(外键)
  • TenderSubTypeId(整数)
  • AmountBaseCurrency(小数)

如何查找所有具有至少两笔付款的TransactionNumbers,其中TenderSubTypeId = 31TenderSubTypeId = 37,并且它们的AmountBaseCurrency均小于0?

我创建的以下查询返回了至少有其中之一的两个TenderSubTypeIds的数据,但如何检查两者在一个Transaction中,并仅返回TransactionNumber

select * from pos.[transaction] t
left join pos.[payment] p on t.id = p.transactionid
where (p.TenderSubTypeId = 31 or p.TenderSubTypeId = 37)
and t.AmountTotalBaseCurrency < 0
英文:

I've got two tables.

pos.transaction:
- Id (primary key)
- MainframeTransactionSequenceNumber (string)
- TransactionNumber (string)

pos.payment:
- Id (primary key)
- TransactionId (foreign key)
- TenderSubTypeId (int)
- AmountBaseCurrency (decimal)

How can I find out all the TransactionNumbers that have at least two payments where the TenderSubTypeId = 31 and TenderSubTypeId = 37 and both their AmountBaseCurrency &lt; 0?

This query below that I've created returns data where there's at least one of the two TenderSubTypeIds but how can I check for both in a Transaction and return just the TransactionNumber?

select * from pos.[transaction] t
left join pos.[payment] p on t.id = p.transactionid
where (p.TenderSubTypeId = 31 or p.TenderSubTypeId = 37)
and t.AmountTotalBaseCurrency &lt; 0

答案1

得分: 1

你可以在子查询中使用两个 HAVING 子句。每个子句计算特定 TenderSubTypeIdpayment 数量。这样可以避免在表上进行两次查找。

SELECT
  t.*
FROM pos.transaction t
WHERE EXISTS (SELECT 1
    FROM pos.payment p 
    WHERE t.id = p.transactionid
      AND p.TenderSubTypeId IN (31, 37)
      AND t.AmountTotalBaseCurrency &lt; 0
    HAVING COUNT(CASE WHEN p.TenderSubTypeId = 31 THEN 1 END) &gt; 0
       AND COUNT(CASE WHEN p.TenderSubTypeId = 37 THEN 1 END) &gt; 0
);

你可以使用一个子句来实现,使用 HAVING COUNT(DISTINCT p.TenderSubTypeId) = 2,但这需要对 p.TenderSubTypeId 进行排序。

英文:

You can use two HAVING clauses inside a subquery. Each clause counts up the number of payment for a particular TenderSubTypeId. This avoids having to do two lookups on the table.

SELECT
  t.*
FROM pos.transaction t
WHERE EXISTS (SELECT 1
    FROM pos.payment p 
    WHERE t.id = p.transactionid
      AND p.TenderSubTypeId IN (31, 37)
      AND t.AmountTotalBaseCurrency &lt; 0
    HAVING COUNT(CASE WHEN p.TenderSubTypeId = 31 THEN 1 END) &gt; 0
       AND COUNT(CASE WHEN p.TenderSubTypeId = 37 THEN 1 END) &gt; 0
);

You could make it one clause using HAVING COUNT(DISTINCT p.TenderSubTypeId) = 2 but that requires a sort on p.TenderSubTypeId.

答案2

得分: 0

你可以使用两个EXISTS谓词来检查相关的表格。

例如:

select *
from transaction t
where exists (select 1 from payment p where p.transactionid = t.id 
              and p.tendersubtype = 31 and amounttotalbasecurrency < 0)
  and exists (select 1 from payment p where p.transactionid = t.id 
              and p.tendersubtype = 37 and amounttotalbasecurrency < 0)
英文:

You can use two EXISTS predicates that check the related table.

For example:

select *
from transaction t
where exists (select 1 from payment p where p.transactionid = t.id 
              and p.tendersubtype = 31 and amounttotalbasecurrency &lt; 0)
  and exists (select 1 from payment p where p.transactionid = t.id 
              and p.tendersubtype = 37 and amounttotalbasecurrency &lt; 0)

答案3

得分: 0

尝试将 pos.[transaction] 表与 pos.[payment] 表两次连接,筛选出具有特定 TenderSubTypeId 值和负 AmountBaseCurrency 的支付。然后按 TransactionNumber 对结果进行分组,仅选择那些至少有两笔不同支付的分组,并提供满足条件的 TransactionNumbers

SELECT t.TransactionNumber
FROM pos.[transaction] t
JOIN pos.[payment] p1 ON t.Id = p1.TransactionId
JOIN pos.[payment] p2 ON t.Id = p2.TransactionId
WHERE p1.TenderSubTypeId = 31
  AND p1.AmountBaseCurrency < 0
  AND p2.TenderSubTypeId = 37
  AND p2.AmountBaseCurrency < 0
GROUP BY t.TransactionNumber
HAVING COUNT(DISTINCT p1.Id) >= 2
英文:

Try to join the pos.[transaction] table with the pos.[payment] table twice, filtering for payments with specific TenderSubTypeId values and negative AmountBaseCurrency. Then group the results by TransactionNumber and select only those groups that have at least two distinct payments, providing the TransactionNumbers that satisfy your condition

SELECT t.TransactionNumber
FROM pos.[transaction] t
JOIN pos.[payment] p1 ON t.Id = p1.TransactionId
JOIN pos.[payment] p2 ON t.Id = p2.TransactionId
WHERE p1.TenderSubTypeId = 31
  AND p1.AmountBaseCurrency &lt; 0
  AND p2.TenderSubTypeId = 37
  AND p2.AmountBaseCurrency &lt; 0
GROUP BY t.TransactionNumber
HAVING COUNT(DISTINCT p1.Id) &gt;= 2

huangapple
  • 本文由 发表于 2023年7月7日 01:17:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76631172.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定