【问题标题】:How to group by when there is a column with unique data (SQL Server)当存在具有唯一数据的列时如何分组(SQL Server)
【发布时间】:2019-12-20 14:34:09
【问题描述】:

我正在尝试将一组在 SQL Server 中具有唯一列的行组合在一起。

目前,所有数据都被选为标准二维表,正在排序的是 Javascript,但是,由于 JSON 很大,因此对于大型列表来说非常慢。

我希望通过在服务器端转换数据集来提高前端性能,以便更快地渲染 DOM。

我认为这可以通过 SQL group by 函数的某种组合来实现,并且可能在 SQL Server 的较新版本中合并一些较新的函数,例如 openjson

示例表

| a | b | c | uniqueColumn  |
|---|---|---|---------------|
| 1 | 2 | 3 | string1       |
| 1 | 2 | 3 | string2       |
| 4 | 5 | 6 | string3       |

示例选择

select
uniqueColumn
group by 
a,
b,
c

期望的输出

| uniqueSelection1 | uniqueSelection2 |
|------------------|------------------|
| string1          | string3          |
| string2          |                  |

当数据集的一部分是唯一的时,如何将每个唯一组合 a-b-c 分组到自己的集合中?

【问题讨论】:

  • 这个问题不是很清楚。您的示例查询无效,因为您仅按返回的 4 列中的 3 列进行分组,并且第 4 列不是聚合。但所需的输出是完全不清晰的地方。请提供minimal reproducible example,以便其他人可以帮助您。
  • @SeanLange 这就是我遇到的问题。我在想也许我可以做一个while循环并在最后选择聚合表?
  • 这是否意味着您要生成 JSON 输出?
  • @Zhorov JSON 只是唯一的字符串。我将它们列为 JSON 以帮助解释我为什么要这样做。让我更新问题...
  • 此外,“将每个唯一的 a-b-c 选择拆分到自己的表中”是什么意思? “将它们加入主表”是什么意思?这里使用了很多没有任何定义的术语。

标签: json sql-server group-by sql-server-2016


【解决方案1】:

要在上面的 N 列中获得所需结果的输出,其中 N 是唯一 a,b,c 值的数量,这将是很困难的。您在应用程序端的处理可能比在 SQL Server 端编写和执行动态数据透视的速度更快。


相反,如果您有较新的 SQL Server,则使用 FOR JSON AUTO 功能可能会有所帮助,即使它与您想要的输出不完全一样:

SELECT DISTINCT (
        SELECT uniqueColumn
        FROM yourtable
        WHERE a = t.a
            AND b = t.b
            AND c = t.c
        FOR JSON AUTO
        ) AS e
FROM yourtable t;

举个例子:

CREATE TABLE test (a int, b int, c int, d varchar(30));
INSERT INTO test VALUES (1,2,3,'string1');
INSERT INTO test VALUES (1,2,3,'string2');
INSERT INTO test VALUES (4,5,6,'string3');
SELECT DISTINCT (SELECT d FROM test WHERE a=t.a AND b=t.b AND c=t.c FOR JSON AUTO) as e FROM test t;

+-----------------------------------+
|                 e                 |
+-----------------------------------+
| [{"d":"string1"},{"d":"string2"}] |
| [{"d":"string3"}]                 |
+-----------------------------------+

SQLFiddle example


如果您想引入导致此输出的唯一 a,b,c 选择,您可以这样做:

SELECT DISTINCT a,b,c, 
(SELECT d FROM test WHERE a=t.a AND b=t.b AND c=t.c FOR JSON AUTO) as e 
FROM test t
FOR JSON AUTO;

[{"a":1,"b":2,"c":3,"e":[{"d":"string1"},{"d":"string2"}]},{"a":4,"b":5,"c":6,"e":[{"d":"string3"}]}]

SQLFiddle Example

或者是table和json的混合结果:

SELECT DISTINCT a,b,c, 
(SELECT d FROM test WHERE a=t.a AND b=t.b AND c=t.c 
FOR JSON AUTO) as e 
FROM test t;


+---+---+---+-----------------------------------+
| a | b | c |                 e                 |
+---+---+---+-----------------------------------+
| 1 | 2 | 3 | [{"d":"string1"},{"d":"string2"}] |
| 4 | 5 | 6 | [{"d":"string3"}]                 |
+---+---+---+-----------------------------------+

SQLFiddle Example


如果您想从 json 数组中释放那些 d 输出,也可以使用 FOR JSON AUTO, WITHOUT_ARRAY_WRAPPER。您对最后一个查询的输出将是

[{"a":1,"b":2,"c":3,"e":"{\"d\":\"string1\"},{\"d\":\"string2\"}"},{"a":4,"b":5,"c":6,"e":"{\"d\":\"string3\"}"}]

快速解释发生了什么:

基本上,对于d 列(您的唯一字符串)的这个子查询,我们正在做类似的事情:

SELECT a,b,c,AGGREGATE_IN_JSON(d) FROM yourtable GORUP BY a,b,c; 

只是语法要求我们在子查询中执行AGGREGATE_IN_JSON 组成的公式。

【讨论】:

    【解决方案2】:

    您需要使用一个函数将这些 json 连接成一列。东西,可能,但如果你有一个更新版本的sql server,它可能是STRING_AGG。看看下面的例子

    SELECT a, b, c, STUFF((SELECT N', ' + s.[CITY] FROM yourTable s 
                 WHERE s.a = st.a
                 AND   s.b = st.b
                 AND   s.c = st.c
                 FOR XML PATH(''),TYPE)
      .value('text()[1]','nvarchar(max)'),1,2,N'')
    FROM yourTable st
    GROUP BY a, b, c
    

    【讨论】:

      猜你喜欢
      • 2014-03-07
      • 2020-04-05
      • 2011-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多