我的数据如下:
|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后跟更新可能实际上是更高效的方法!