1

是否可以在 MySQL 中使用 SUM 以外的聚合来透视行?我一直在网上寻找,并通过我的课程书。但是,我什么也找不到。

4

1 回答 1

2

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

用于COUNT()计算行数(如SUM()

因为聚合函数会消除NULL值,所以您有时会遇到类似于SUM(CASE...)您可能习惯看到的模式(其表达式返回 1 或 0,它们会相加)。除了SUM()在此方法中使用聚合,您可以使用 aCOUNT()代替,前提是它的表达式返回一个值(任何值)或 a NULLNULLs 被消除,并且计数返回的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()这与使用and zeros 和 one可以完成的基本相同:

使用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()旋转键/值对列表:

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

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

...你想要这样的结果:

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

在这种情况下,您可以使用 aMAX()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()聚合,您可以通过摆脱NULLs有效地将其折叠为一行

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

于 2013-01-25T03:42:34.693 回答