如何在同一查询的另一列中引用聚合列?

Posted

技术标签:

【中文标题】如何在同一查询的另一列中引用聚合列?【英文标题】:How can I reference an aggregate column in another column in the same query? 【发布时间】:2013-07-08 09:33:03 【问题描述】:

我的查询看起来或多或少像这样:

INSERT INTO #results
SELECT Name, 
        (SELECT 
            SUM(CAST(Amount AS BIGINT)) 
         FROM Items 
         WHERE RemittingMember = a.Number 
            and RecordId = 50), 
        (SELECT SUM(CAST(Std_Amount AS BIGINT)) 
         FROM Items 
         WHERE RemittingMember = a.Number 
            AND RecordId = 10)
FROM Member a

其中Amount 是货币(存储为varchar,没有小数点),RemittingMemberItems 表和Member 表之间的链接,RecordId 表示该行的项目类型是。在这种情况下,50 是借方,10 是贷方。

我需要从第二列中减去第一列,并将该值放在第三列中。我知道我可以这样做:

INSERT INTO #results
SELECT Name, 
            (SELECT 
                SUM(CAST(Amount AS BIGINT)) 
             FROM Items 
             WHERE RemittingMember = a.Number 
                and RecordId = 50), 
            (SELECT SUM(CAST(Std_Amount AS BIGINT)) 
             FROM Items 
             WHERE RemittingMember = a.Number 
                AND RecordId = 10),
             (SELECT 
                SUM(CAST(Amount AS BIGINT)) 
             FROM Items 
             WHERE RemittingMember = a.Number 
                and RecordId = 50) - (SELECT SUM(CAST(Std_Amount AS BIGINT)) 
             FROM Items 
             WHERE RemittingMember = a.Number 
                AND RecordId = 10)    
FROM Member a

但是如果需要进行更改,这将很难阅读并且更改起来很麻烦。我也知道我可以使用局部变量来做到这一点,但这是一份报告,其中a.Number 将发生变化,这将涉及我想要避免的迭代。

我还需要检查第三列的符号以将值放入第四列。

有没有聪明的方法来实现这一点?

【问题讨论】:

【参考方案1】:

您应该能够进一步简化查询,以删除对 items 表的附加连接。像这样的东西应该工作。 需要使用您的数据进行测试

SELECT
    name, 
    debit, 
    credit, 
    Amount = debit - credit, 
    [SIGN] = SIGN(debit - credit)
FROM Member a
inner join(
     SELECT 
        RemittingMember,
        debit=SUM(CASE WHEN RecordId = 50 THEN CAST(Amount AS BIGINT) ELSE 0 END),
        credit=SUM(CASE WHEN RecordId = 10 THEN CAST(Std_Amount AS BIGINT) ELSE 0 END)
     FROM Items 
     WHERE RecordId IN(10,50)
     GROUP BY
        RemittingMember
) as Amts
    on Amts.RemittingMember = a.Number 

【讨论】:

【参考方案2】:

您可以使用 CTE,如下所示:

;WITH intermediate_results (name, debit, credit)
AS (
SELECT
    Name
    AS name, 

    (SELECT 
        SUM(CAST(Amount AS BIGINT)) 
     FROM Items 
     WHERE RemittingMember = a.Number 
        and RecordId = 50)
    AS debit, 

    (SELECT SUM(CAST(Std_Amount AS BIGINT)) 
     FROM Items 
     WHERE RemittingMember = a.Number 
        AND RecordId = 10)
    AS credit

FROM Member a
)

INSERT INTO #results
SELECT name, debit, credit, debit - credit, SIGN(debit - credit)
  FROM intermediate_results

【讨论】:

更新:在结果 SELECT 语句中添加了第五列【参考方案3】:

你可以使用outer apply声明:

INSERT INTO #results
SELECT Name, 
        s1.Value, 
        s2.Value,
        s2.Value - s1.Value,
        case
            when s2.Value > s1.Value then 1
            when s2.Value < s1.Value then -1
            else 0
        end
FROM Member a
    outer apply (SELECT 
            SUM(CAST(Amount AS BIGINT)) Value
         FROM Items 
         WHERE RemittingMember = a.Number 
            and RecordId = 50) s1
    outer apply (SELECT 
            SUM(CAST(Std_Amount AS BIGINT)) Value
         FROM Items 
         WHERE RemittingMember = a.Number 
            and RecordId = 10) s2

【讨论】:

你是第一个,但在我的情况下 CTE 更快:) 当我回答 CTE 时,我也喜欢这个答案。顺便说一句,可能因为计算符号列而速度较慢。 CASE 太慢,尝试使用SIGN() function 另外,将第五列添加到 CTE 答案并再次运行测试:-)

以上是关于如何在同一查询的另一列中引用聚合列?的主要内容,如果未能解决你的问题,请参考以下文章

如果同一表的另一列中存在值,如何找到对应的列值

删除同一列或连续行的另一列中具有特定值和缺失值的行

如何将一列的列值组合到 MySQL 中的另一列中?

如何参考r中另一列中的另一个单元格值更改列中的单元格值?

如何根据 Row_id 列将值写入数据框的另一列并且匹配列中存在值?

如何根据 PySpark 数据框的另一列中的值修改列? F.当边缘情况