SQL:按选定列对记录进行分组
Posted
技术标签:
【中文标题】SQL:按选定列对记录进行分组【英文标题】:SQL: Grouping records by selected columns 【发布时间】:2019-08-23 07:57:06 【问题描述】:我的表是这样的(名称 = TMaster)
A B C D
1 1 1 X
1 1 1 Y
1 1 1 Z
2 2 2 Y
3 3 3 Y
3 3 3 Z
我想这样显示:
A B C DX DY DZ
1 1 1 X Y Z
2 2 2 Y
3 3 3 Y Z
我尝试过的解决方案:
我尝试创建一个不同的表,如下所示:(Name TUnique)
A B C
1 1 1
2 2 2
3 3 3
然后尝试使用其中一列(A 或 B 或 C)将其与原始表外部连接。但它会返回如下输出:
A B C DX DY DZ
1 1 1 X Y Z
我也尝试过 Union 运算符,但没有运气。将“ ”作为创建的唯一表中的列,但最终会创建太多重复记录。
这是我尝试过的 SQL 代码:
SELECT
Ta.A,
Ta.B,
Ta.C,
Tm1.D,
Tm2.D,
Tm3.D
FROM
TUnique Ta,
TUnique Tb,
TUnique Tc,
TMaster Tm1,
TMaster Tm2,
TMaster Tm3
WHERE
Tm1.A = Ta.A (+)
AND Tm1.D="X"
Tm2.A = Tb.A (+)
AND Tm2.D="Y"
Tm3.A = Tc.A (+)
AND Tm3.D="X";
这也返回相同的记录。
SELECT
Ta.A,
Ta.B,
Ta.C,
Tm1.D,
Tm2.D,
Tm3.D
FROM
TUnique Ta,
TUnique Tb,
TUnique Tc,
TMaster Tm1,
TMaster Tm2,
TMaster Tm3
WHERE
Tm1.A (+) = Ta.A
AND Tm1.D="X"
Tm2.A (+) = Tb.A
AND Tm2.D="Y"
Tm3.A (+) = Tc.A
AND Tm3.D="X";
【问题讨论】:
今日提示:始终使用现代、明确的JOIN
语法。更容易编写(没有错误),更容易阅读(和维护),如果需要更容易转换为外连接
您使用的是哪个 dbms?这种奇怪的外连接语法已被弃用并且是特定于产品的。
五月 (1,1,1) 有几个 Y 行?
甚至 Oracle 都建议停止使用专有的 (+)
进行外部连接
【参考方案1】:
您可以使用pivot
查询:
select *
from
( select * from tab )
pivot
(
max(D) for D in ( 'X' as dx, 'Y' as dy, 'Z' as dz )
)
order by A;
A B C DX DY DZ
- - - -- -- --
1 1 1 X Y Z
2 2 2 Y
3 3 3 Y Z
Demo
【讨论】:
【参考方案2】:您可以使用条件聚合来旋转您的 D
值:
SELECT A, B, C,
MAX(CASE WHEN D='X' THEN D END) AS DX,
MAX(CASE WHEN D='Y' THEN D END) AS DY,
MAX(CASE WHEN D='Z' THEN D END) AS DZ
FROM TMaster
GROUP BY A, B, C
输出
A B C DX DY DZ
1 1 1 X Y Z
2 2 2 null Y null
3 3 3 null Y Z
Demo on dbfiddle
【讨论】:
。 .关于空字符串的注释不适用于将空字符串 视为NULL
的 Oracle。
@GordonLinoff 谢谢你。当我回答这个问题时,这个问题没有被标记为 Oracle,我也没有注意到这个变化。这是有趣的行为;你知道他们为什么这样做吗?
。 . Oracle 早于该标准。在 1980 年代初期,这似乎是个好主意。
@GordonLinoff 喜欢很多东西! :-)以上是关于SQL:按选定列对记录进行分组的主要内容,如果未能解决你的问题,请参考以下文章