Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 找到满足两种不同聚合标准的记录的更好方法?_Sql_Sql Server_Sum_Aggregate Functions_Sql Server 2016 - Fatal编程技术网

Sql 找到满足两种不同聚合标准的记录的更好方法?

Sql 找到满足两种不同聚合标准的记录的更好方法?,sql,sql-server,sum,aggregate-functions,sql-server-2016,Sql,Sql Server,Sum,Aggregate Functions,Sql Server 2016,我需要找到信贷交易总额大于或等于阈值金额,而借方交易总额小于或等于相同阈值金额的倒数的客户。我还想返回总交易金额满足信用和借记阈值的交易。我提出了两个解决方案,但我认为我可能会使事情变得比必要的更复杂 下面是一些简化的示例数据 TransactionID CustomerID TransactionDate TransactionType TransactionAmount ------------- ---------- --------------- -------------

我需要找到信贷交易总额大于或等于阈值金额,而借方交易总额小于或等于相同阈值金额的倒数的客户。我还想返回总交易金额满足信用和借记阈值的交易。我提出了两个解决方案,但我认为我可能会使事情变得比必要的更复杂

下面是一些简化的示例数据

TransactionID  CustomerID  TransactionDate  TransactionType  TransactionAmount
-------------  ----------  ---------------  ---------------  -----------------
1              1           2020-10-01       Credit           10.25
2              1           2020-10-02       Credit           11.50
3              1           2020-10-02       Debit            -13.25
4              2           2020-10-01       Credit           14.22
5              2           2020-10-02       Debit            -50.75
6              2           2020-10-04       Credit           12.85
7              2           2020-10-07       Debit            -4.53
8              3           2020-10-02       Credit           12.85
CustomerID 2的阈值金额为20美元,是唯一一个信用和借记都达到该阈值的客户。这是我的预期结果

TransactionID  CustomerID  TransactionDate  TransactionType  TransactionAmount
-------------  ----------  ---------------  ---------------  -----------------
4              2           2020-10-01       Credit           14.22
6              2           2020-10-04       Credit           12.85
5              2           2020-10-02       Debit            -50.75
7              2           2020-10-07       Debit            -4.53
我提出了两个解决办法。我应该提到,由于我最终需要嵌入这个查询的软件,我不能使用临时表或表变量

解决方案1


下面是我的示例数据插入和两个解决方案的示例。如果我不能使用临时表或表变量,有没有更好的方法来执行此操作?

您可以使用窗口函数:

select transactionid, customerid, transactiondate, transactiontype, transactionamount
from (
    select t.*,
        sum(case when transactiontype = 'Credit' then transactionamount else 0 end) 
            over(partition by customerid) sum_credit,
        sum(case when transactiontype = 'Debit' then transactionamount else 0 end) 
            over(partition by customerid) sum_debit
    from transactions t
) t
where sum_credit > @ThresholdAmount and sum_debit < - @ThresholdAmount
order by customerid, transactiontype, transactiondate

在子查询中,条件和计算每个客户的借方和贷方总额。然后,您可以使用此信息在外部查询中进行筛选。

也许您所追求的是HAVING中的某个条件聚合?尽管这不会返回任何行,因为没有客户的信贷交易总额大于阈值金额,而借方交易总额大于相同的阈值金额。这是因为所有借记交易都有负值,负值之和永远不能为正值,因此永远不能大于示例中的值20:

声明@ThresholdAmount NUMERIC10,2; 设置@ThresholdAmount=20.00; 选择CustomerID 来自dbo.Transactions 按客户ID分组 当'Credit'然后TransactionMount END>@ThresholdAmount时具有SUMCASE TransactionType 当'Debit'然后TransactionMount END>@ThresholdAmount时的SUMCASE TransactionType和SUMCASE TransactionType;
我需要澄清这个要求。给定20美元的阈值金额,我正在寻找信用交易总额大于或等于该阈值金额,而借记交易总额小于或等于该阈值金额的倒数的客户。因此,如果客户在借记交易中有-30美元,我会说他们达到了阈值。如果我将HAVING子句的最后一部分更改为<@ThresholdAmount*-1,则我将获得客户ID 2。我为不准确的要求道歉。我是用商业术语而不是技术术语来思考的。
WITH txn_cte (TransactionID, CustomerID, TransactionDate, TransactionType, TransactionAmount, TransactionAmountTotal) AS
(
    SELECT
          txn.TransactionID
        , txn.CustomerID
        , txn.TransactionDate
        , txn.TransactionType
        , txn.TransactionAmount
        , txn.TransactionAmountTotal
    FROM  (
              SELECT
                   TransactionID
                 , CustomerID
                 , TransactionDate
                 , TransactionType
                 , TransactionAmount
                 , SUM(TransactionAmount) OVER (PARTITION BY CustomerID, TransactionType) AS [TransactionAmountTotal]
              FROM Transactions
          ) txn
    WHERE ABS(txn.TransactionAmountTotal) >= @ThresholdAmount
)
SELECT
         txn_cte.TransactionID
       , txn_cte.CustomerID
       , txn_cte.TransactionDate
       , txn_cte.TransactionType
       , txn_cte.TransactionAmount
FROM     txn_cte
WHERE    EXISTS (
                    SELECT txn_cte1.TransactionID
                    FROM   txn_cte txn_cte1
                    WHERE  txn_cte1.TransactionType        = 'Credit'
                       AND txn_cte1.CustomerID             = txn_cte.CustomerID
                )
     AND EXISTS (
                    SELECT txn_cte2.TransactionID
                    FROM   txn_cte txn_cte2
                    WHERE  txn_cte2.TransactionType        = 'Debit'
                       AND txn_cte2.CustomerID             = txn_cte.CustomerID
                )
ORDER BY txn_cte.CustomerID
       , txn_cte.TransactionType
       , txn_cte.TransactionDate;
select transactionid, customerid, transactiondate, transactiontype, transactionamount
from (
    select t.*,
        sum(case when transactiontype = 'Credit' then transactionamount else 0 end) 
            over(partition by customerid) sum_credit,
        sum(case when transactiontype = 'Debit' then transactionamount else 0 end) 
            over(partition by customerid) sum_debit
    from transactions t
) t
where sum_credit > @ThresholdAmount and sum_debit < - @ThresholdAmount
order by customerid, transactiontype, transactiondate