SQL条件分组和求和

我的数据如下:

|cat |subcat |amount|
---------------------
|A   |1      |123   |
|A   |2      |456   |
|B   |1      |222   |
|B   |2      |333   |

在第一种情况下,我需要用cat和subcat求和.简单:

SELECT cat, subcat, sum(amount) FROM data GROUP BY cat, subcat

接下来,我有一个更复杂的要求,对于某些猫,金额应该“推”到给定的子猫.这可以存储在另一个配置表中:

|cat |subcat|
-------------
|B   |1     |

这告诉我,对于所有cat =’B’行,该数量应被视为subcat = 1.此外,其中cat =’B’和subcat<> 1该金额应报告为零.换句话说,我需要的结果是:

|cat |subcat|amount|
|A   |1     |123   |
|A   |2     |456   |
|B   |1     |555   |
|B   |2     |0     |

我无法更新我的数据表.当然我可以在proc中使用SELECT … INTO并在那里修复数据,但我想知道它是否可以在一次点击中完成.

我可以非常接近:

SELECT data.cat,
    ISNULL(config.subcat, data.subcat),
    SUM(amount)
FROM data
    LEFT OUTER JOIN config ON (data.cat = config.cat)
GROUP BY data.cat, ISNULL(config.subcat, data.subcat)

…但是我第二次要求显示cat:B,subcat:2为零.

可能吗?

我正在使用Sybase IQ 12.5(即旧的T-SQL,但是有一个case语句,我怀疑它可能有用)

最佳答案 这就是我想出来的.

SELECT cat, subcat, sum(amount)
FROM
(
    SELECT d.cat,
        d.subcat,
        CASE WHEN c.subcat <> d.subcat THEN 0 ELSE amount END amount
    FROM data d
        LEFT OUTER JOIN config c ON (d.cat = c.cat)
    UNION    
    SELECT d.cat,
        ISNULL(c.subcat, d.subcat),
        amount
    FROM data d
        LEFT OUTER JOIN config c ON (d.cat = c.cat)
    WHERE c.subcat <> d.subcat
) AS data2
GROUP BY cat, subcat

鉴于它使用带有union的派生表,并且我的实际数据集比我在问题中给出的数据集大得多,我认为SELECT … INTO后跟更新可能实际上是更高效的方法!

点赞