【问题标题】:Return all the distinct values of column B in one row for each distinct value in column A对于 A 列中的每个不同值,在一行中返回 B 列的所有不同值
【发布时间】:2015-12-15 09:27:10
【问题描述】:

取下表:

CREATE TABLE boxes (
    box integer,
    color character varying,
    size integer,
    ...
);

boxcolor 都可以假设不是唯一值 设置。

查询此表:

SELECT color, box FROM boxes;

结果会是这样的:

+-------+-----+
| color | box |
+-------+-----+
| blue  |   2 |
| blue  |   3 |
| blue  |   4 |
| green |   1 |
| green |   3 |
| red   |   1 |
| red   |   2 |
| red   |   2 |
+-------+-----+

是否可以以这样的方式查询该表,使得结果有两列,一列有一个数组(或字符串或列表),每个不同的box 值都有不同的color

结果应该是这样的:

+-------+-----------+
| color | box_types |
+-------+-----------+
| blue  | {2,3,4}   |
| green | {1,3}     |
| red   | {1,2}     |
+-------+-----------+

其中color 列必须包含唯一值,并且每行在聚合列中必须仅包含不同的box 数字。

鉴于这个问题的不可知性,我想为主要 DBMS 收集所有最佳解决方案。回答时,请指定每个查询适用于哪个 DBMS。

【问题讨论】:

  • 这不是真正的 SQL 做事方式。但是,一些 dbms 产品具有 GROUP_CONCAT 和 STUFF 等功能。
  • 我想有人必须将所有答案合并为一个......
  • 是的,这就是目的。
  • 既然你做了 GROUP BY 颜色,没有 DISTINCT 的 SELECT 就可以了。 (通常 GROUP BY 时不需要 SELECT DISTINCT。)
  • 经过更多测试后,我发现仅使用 group_concat()array_agg() 之类的函数不会从结果聚合列中删除​​重复项。我对问题进行了编辑,以更清楚地说明每个结果行必须只包含不同的框值。

标签: sql concatenation aggregate-functions


【解决方案1】:

嗯,在 MySQL 中,您可以执行以下操作:

select color, group_concat(box) from tbl group by color

在甲骨文中:

select color, wm_concat(box) from tbl group by color

【讨论】:

  • 没有必要添加大括号,它们在您使用数组列而不是一个字符串进行分组的情况下的答案中。因此,SELECT color, group_concat(box) FROM boxes GROUP BY color; 可能会很好,如果你找到方法只获取每个 color 的所有不同的 box 数字。
【解决方案2】:

试试下面。

SELECT
    color ,
     STUFF(
         (SELECT DISTINCT ',' +CONVERT(varchar(10), box)   
          FROM boxes 
          WHERE color = a.color 
          FOR XML PATH (''))
          , 1, 1, '') AS box_types
FROM boxes  AS a
GROUP BY color;

查看SQL Fiddle

【讨论】:

  • 这是 MS SQL Server 的有效答案。请注意,大括号在答案中,因为它是数组列而不是字符串。我已将它们从您的回答中删除。
【解决方案3】:

首先,这是对“规范化”原则的否定,或者说它是“坏的”。

但是,有一些 dbms,如 Microsoft SQL Server,通过子句 PIVOT(及其相反的 UNPIVOT)实现了这种可能性。

此子句允许创建一个表(使用您的示例),如下所示:

+--------+------+------+------+ |颜色 |盒子1 |盒子2 |盒子3 | +--------+------+------+------+ |蓝色 | 2 | 3 | 4 | |绿色 | 1 | 3 |空 | |红色 | 1 | 2 |空 | +--------+------+------+------+

【讨论】:

  • 我认为您需要知道确切的-to beproduce-列才能使用PIVOT
  • 现代 DBMS 支持数组列。如果他们“否定规范化原则”,这不会阻止用户从他们的使用中受益。最后,这只是一种转换数据的方法,使它们更适合您的需求。以您将数据存储在一个数据库表中但您需要在另一个数据库表中以不同方式使用它们的情况为例。在示例中,“每种颜色的所有不同框号”只不过是一个值。
  • 你是对的,但是——据我所知——如果它不是第五范式,你就不能称它为 RDBMS。这张表连第三都没有!!!
猜你喜欢
  • 1970-01-01
  • 2012-05-25
  • 1970-01-01
  • 1970-01-01
  • 2021-11-14
  • 2021-01-25
  • 2017-08-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多