首页 >数据库 >mysql教程 >如何在SQL中高效地执行交叉表查询?

如何在SQL中高效地执行交叉表查询?

Patricia Arquette
Patricia Arquette原创
2025-01-20 22:23:11366浏览

How to Efficiently Perform a Crosstab Query in SQL?

使用CASE和GROUP BY实现动态替代PIVOT

问题:

下表所示数据以行和列的形式组织。目标是将其转换为具有动态列数的表,其中每列代表按指定类别分组的值。

id feh bar
1 10 A
2 20 A
3 3 B
4 4 B
5 5 C
6 6 D
7 7 D
8 8 D

期望输出:

bar val1 val2 val3
A 10 20
B 3 4
C 5
D 6 7 8

原始查询:

以下查询使用CASE表达式和GROUP BY来实现所需结果:

<code class="language-sql">SELECT bar, 
MAX(CASE WHEN abc."row" = 1 THEN feh ELSE NULL END) AS "val1",
MAX(CASE WHEN abc."row" = 2 THEN feh ELSE NULL END) AS "val2",
MAX(CASE WHEN abc."row" = 3 THEN feh ELSE NULL END) AS "val3"
FROM
(
  SELECT bar, feh, row_number() OVER (partition by bar) as row
  FROM "Foo"
 ) abc
GROUP BY bar </code>

高效的交叉表替代方案:

为了提高效率和可读性,可以使用tablefunc模块中的crosstab函数来实现动态解决方案。以下是一个示例:

<code class="language-sql">SELECT * FROM crosstab(
  'SELECT bar, 1 AS cat, feh
   FROM tbl_org
   ORDER BY bar, feh')
 AS ct (bar text, val1 int, val2 int, val3 int);  -- 更多列?</code>

处理多个值:

对于同一类别下有多个值的场景,可以将crosstab函数扩展为以下形式:

<code class="language-sql">SELECT * FROM crosstab(
  'SELECT bar, val, feh
   FROM tbl_org
   ORDER BY 1, 2')
 AS ct (bar text, val1 int, val2 int, val3 int);  -- 更多列?</code>

内置交叉表函数:

tablefunc模块还为特定列数提供了预定义的crosstab函数:

<code class="language-sql">SELECT * FROM crosstab3('SELECT row_name, attrib, val FROM tbl ORDER BY 1,2');</code>

这些函数使调用更简单,并默认处理文本数据。

动态返回类型:

虽然tablefunc简化了流程,但在处理动态返回类型方面存在局限性。为了解决这个问题,可以考虑其他方法,例如使用PL/pgSQL函数或创建动态SQL语句。

以上是如何在SQL中高效地执行交叉表查询?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn