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:按选定列对记录进行分组的主要内容,如果未能解决你的问题,请参考以下文章

如何按列对pyspark中的数据框进行分组并以该列作为键并以记录列表作为其值来获取字典?

sql中group by 是啥意思啊?请教谢谢

按 ID 和更新列对 SQL 中的行进行分组

Oracle sql查询按日期对连续记录进行分组

数据库查询选择所有列,包括按“分组依据”的每条记录的计数

group by分组后获得每组中时间最大的那条记录