SQL在SELECT语句

时间:2018-04-20 10:04:10

标签: sql group-by

我有一个GROUP BY查询,它似乎在GROUP BY子句中使用了非聚合数据而不是,我认为这不会起作用。

我被要求编写一个转换以下数据的查询:

| item | type | cost | category |
|------|------|------|----------|
| 1    | X    | 10   | A        |
| 1    | Y    | 20   | A        |
| 2    | X    | 30   | B        |
| 2    | Y    | 40   | B        |
| 3    | X    | 50   | C        |
| 3    | Y    | 60   | C        |
| 4    | X    | 70   | D        |
| 4    | Y    | 80   | D        |

进入这个:

| item | x  | y  | category |
|------|----|----|----------|
| 1    | 10 | 20 | A        |
| 2    | 30 | 40 | B        |
| 3    | 50 | 60 | C        |
| 4    | 70 | 80 | D        |

注意:

  • 传入的数据显然未正常化
  • item是唯一的,但每个type值重复一次
  • category对于相同item
  • 的行相同

我最终得到了以下解决方案:

SELECT
    item,
    sum(CASE WHEN type='X' THEN cost END) as X,
    sum(CASE WHEN type='Y' THEN cost END) as Y,
    category
FROM data
GROUP BY item,category;

让我感到惊讶的是它起作用了。让我感到惊讶的是它适用于PostgreSQL,MariaDB(ANSI模式),Microsoft SQL和SQLite。

注意: - 我在category中添加了GROUP BY只是为了让它出现在SELECT子句中。 - 我使用了sum()函数,即使只有一个值,也只是将它包含在SELECT子句中。

想到我无法在type列中使用SELECT列,因为它不在GROUP BY中且未汇总。实际上,如果我尝试单独选择它,查询将失败。

问题是,当我无法单独使用type运算符时,我如何使用CASE列?

1 个答案:

答案 0 :(得分:3)

您对“未组合”列的使用完全没问题。

规则是:“SELECT列表中的每个表达式必须是聚合函数,或者它必须是GROUP BY的一部分”。

聚合内部使用了列type sum(CASE WHEN type='X' THEN cost END) as Xsum(cost)max(type)没有什么不同。

如果您使用标准SQL filter选项,则会更加明显:

sum(CASE WHEN type='X' THEN cost END)

与:

相同
sum(cost) filter (where type = 'X')

然而,只有极少数DBMS支持此标准。