使用SUM以外的聚合来旋转行?

时间:2013-01-25 03:07:13

标签: mysql sql

是否可以在MySQL中使用除SUM之外的聚合来转动行? 我一直在网上看,通过我的课程书。但是,我找不到任何东西。

1 个答案:

答案 0 :(得分:2)

简短回答 - 是的,您可以根据您需要执行的查询类型来使用其他聚合 - 每个聚合都可以用于特定目的。

使用COUNT()来计算行数(例如SUM()

因为聚合函数消除了NULL值,所以有时会遇到类似于您可能习惯看到的SUM(CASE...)的模式(其表达式返回1或0,这会被加起来)。如果此表达式返回值(任何值)或SUM(),则可以使用COUNT()来代替在此方法中使用NULL聚合。 NULL被删除,COUNT()计算返回的非空行。这仅用于计算值

以下是使用val = 1聚合计算COUNT()的每个组的行数的示例。假设您有下表,并希望结果为列a, b

group value
 a     1
 a     1
 a     2
 b     1
 b     2

使用COUNT()

SELECT 
  `group`,
  /* the aggregate eliminates NULLs (rows where val <> 1) */
  COUNT(CASE WHEN `group` = 'a' THEN val ELSE NULL END) AS `a`,
  COUNT(CASE WHEN `group` = 'b' THEN val ELSE NULL END) AS `b`
FROM pivot
WHERE val = 1

结果:

 a      b
-------------
 2      1

示范:http://sqlfiddle.com/#!2/b4585/7

这与使用SUM()以及0和1可以完成的基本相同:

使用SUM()就像你可能已经看到的那样完成了同样的事情:

SELECT 
  /* the aggregate eliminates NULLs (rows where val <> 1) */
  SUM(CASE WHEN `group` = 'a' THEN 1 ELSE 0 END) AS `a`,
  SUM(CASE WHEN `group` = 'b' THEN 1 ELSE 0 END) AS `b`
FROM pivot
WHERE val = 1

示范:http://sqlfiddle.com/#!2/b4585/8


使用MAX()来转动键/值对列表:

有时,您只想更改从行到列的1对1映射。如果您需要展平键/值对列表,这很有用。假设您有一个这样的表,每列只有一行要转出:

key    value
------------
k1     v1
k2     v2
k3     v3

...你想得到这样的结果:

k1  k2  k3
-----------
v1  v2  v3

在这种情况下,您可以使用MAX()MIN()聚合,因为NULL值将被聚合消除,只返回实际具有非null值的值,因此是MAX()

因此,这个查询会转动它们但会产生3行,每行只有一行非空:

SELECT
  CASE WHEN `key` = 'k1' THEN `value` ELSE NULL END AS `k1`,
  CASE WHEN `key` = 'k2' THEN `value` ELSE NULL END AS `k2`,
  CASE WHEN `key` = 'k3' THEN `value` ELSE NULL END AS `k3`
FROM key_value

结果:

k1   k2   k3
---------------
v1   NULL NULL
NULL v2   NULL
NULL NULL v3

示范:http://sqlfiddle.com/#!2/813b3/5

通过使用MAX()聚合,您可以通过删除NULL来有效地将其折叠为一行

SELECT
  MAX(CASE WHEN `key` = 'k1' THEN `value` ELSE NULL END) AS `k1`,
  MAX(CASE WHEN `key` = 'k2' THEN `value` ELSE NULL END) AS `k2`,
  MAX(CASE WHEN `key` = 'k3' THEN `value` ELSE NULL END) AS `k3`
FROM key_value

给出我们想要的结果 - 一行转出:

k1  k2  k3
-----------
v1  v2  v3

示范:http://sqlfiddle.com/#!2/813b3/4