【问题标题】:Can I Group By an Unknown Number of Columns?我可以按未知数量的列分组吗?
【发布时间】:2012-09-25 12:41:52
【问题描述】:

我目前正在尝试重写一个存储过程,以考虑我们其中一个表的规范化。在原始过程中,我们有两个表:

CREATE TABLE #t_batch
(batch_id   integer, 
thread_group NVARCHAR(60),
dye_code_1  NVARCHAR(10),
dye_conc_1  NUMERIC(19, 7),
dye_code_2  NVARCHAR(10),
dye_conc_2  NUMERIC(19, 7),
dye_code_3  NVARCHAR(10),
dye_conc_3  NUMERIC(19, 7),
dye_code_4  NVARCHAR(10),
dye_conc_4  NUMERIC(19, 7),
dye_code_5  NVARCHAR(10),
dye_conc_5  NUMERIC(19, 7),
dye_code_6  NVARCHAR(10),
dye_conc_6  NUMERIC(19, 7))

CREATE TABLE #t_group
(group_id   INTEGER IDENTITY(1, 1),
dye_code_1  NVARCHAR(10),
dye_conc_1  NUMERIC(19, 7),
dye_code_2  NVARCHAR(10),
dye_conc_2  NUMERIC(19, 7),
dye_code_3  NVARCHAR(10),
dye_conc_3  NUMERIC(19, 7),
dye_code_4  NVARCHAR(10),
dye_conc_4  NUMERIC(19, 7),
dye_code_5  NVARCHAR(10),
dye_conc_5  NUMERIC(19, 7),
dye_code_6  NVARCHAR(10),
dye_conc_6  NUMERIC(19, 7),
thread_group NVARCHAR(60), 
num_batches INTEGER)

在一些操作之后,#t_batch 被填充了一些记录。然后我们通过以下方式将数据插入#t_group:

INSERT INTO #t_group
(dye_code_1, dye_conc_1, dye_code_2, dye_conc_2, dye_code_3, dye_conc_3,
dye_code_4, dye_conc_4, dye_code_5, dye_conc_5, dye_code_6, dye_conc_6, 
thread_group, num_batches)
SELECT dye_code_1, dye_conc_1, dye_code_2, dye_conc_2, dye_code_3, dye_conc_3, 
dye_code_4, dye_conc_4, dye_code_5, dye_conc_5, dye_code_6, dye_conc_6, 
thread_group, COUNT(batch_id_fk)
FROM #t_batch
GROUP BY dye_code_1, dye_conc_1, dye_code_2, dye_conc_2, dye_code_3, dye_conc_3, 
dye_code_4, dye_conc_4, dye_code_5, dye_conc_5, dye_code_6, dye_conc_6, 
thread_group
ORDER BY dye_code_1, dye_conc_1, dye_code_2, dye_conc_2, dye_code_3, dye_conc_3, 
dye_code_4, dye_conc_4, dye_code_5, dye_conc_5, dye_code_6, dye_conc_6, 
thread_group

因此,我们有一系列记录,这些记录按染料列分组,每个独特的染料组合及其浓度都有一个独特的 group_id。此外,每个组都有一个批次记录的计数。

但是,由于实际上批次的染料数量没有限制,因此表格已经标准化:

CREATE TABLE #t_batch
(batch_id   INTEGER, 
thread_group NVARCHAR(60))

CREATE TABLE #t_batch_dye
(batch_id_fk INTEGER, 
stage   INTEGER,
sequence    INTEGER, 
dye_code    NVARCHAR(10),
dye_conc    NUMERIC(19,7))

CREATE TABLE #t_group
(group_id   INTEGER IDENTITY(1, 1),
thread_group NVARCHAR(60), 
num_batches INTEGER)

CREATE TABLE #t_group_dye
(group_id   INTEGER, 
stage   INTEGER,
sequence    INTEGER,
dye_code    NVARCHAR(10),
dye_conc    NUMERIC(19,7))

现在,我的问题是:假设我们填充了 #t_batch 和 #t_batch_dye 并且 #t_batch 中的每条记录都有不同数量的 #t_batch_dye 记录,我如何将具有唯一 group_id 的记录插入到 #t_group 中每种独特的染料组合及其浓度以及每组的批次计数?

这是我可以使用 PIVOT 关键字的东西吗?我在网上找到的示例似乎都假设预先知道透视字段的数量。

非常感谢,

大卫

苏格兰格拉斯哥


更新:

我所做的是使用一个函数,该函数返回一个串联的代码和 concs 字符串,并用它来对数据进行分组。

DECLARE @dyes NVARCHAR(2000)  

 SELECT @dyes = ISNULL(@dyes,'') + dye_code + ' ' + convert(nvarchar,      requested_dye_conc) + ' '
 FROM   #t_batch_dye
 WHERE  batch_id_fk = @batch_id
 ORDER BY dye_code ASC

【问题讨论】:

    标签: sql-server sql-server-2008 tsql sql-server-2005 stored-procedures


    【解决方案1】:

    您正确地假设PIVOT 和更传统的交叉表查询方法希望您提前知道需要多少列。此时,您需要使用一些动态 SQL 来获得您所追求的:

    【讨论】:

    • 谢谢。我会调查你发布的链接。
    【解决方案2】:

    部分答案,而不是理想答案: 如果您知道染料组合永远不会超过 20 种,您可以使用

    创建另一个临时表
    select b.thread_group, 
    case when d.sequence=1  then d.dye_code end as code1,
    case when d.sequence=1  then d.dye_conc end as conc1,
    case when d.sequence=2  then d.dye_code end as code2,
    case when d.sequence=2  then d.dye_conc end as conc2,
    case when d.sequence=3  then d.dye_code end as code3,
    case when d.sequence=3  then d.dye_conc end as conc3,
    <lots of boring copy&paste...>
    case when d.sequence=20 then d.dye_code end as code20,
    case when d.sequence=20 then d.dye_conc end as conc20
    from #t_batch t, #t_batch_dye d
    where t.batch_id  = d.batch_id
    

    然后从中选择您的组,使用所有 code1 到 conc20。它不漂亮,但很清楚。而且我知道它首先否定了将表格标准化的全部意义!祝你好运。

    【讨论】:

    • 谢谢,文尼。恐怕可能的组合确实很大!
    • 好的。我是根据您原来的 6 工作的。另一个疯狂的想法是您可以连接从表中选择的变量(我认为 - 或者这只是 Sybase?)。您必须使用“更新”语句来完成。因此:update #t_batch_dye set @longstring = @longstring + dye_code + " " +convert(varchar, dye_conc) +" " where batch_id = @nextbatch 这将为您提供每个唯一的字符串。需要更多的工作......
    • 这就是我最终所做的。我使用了一个函数来连接染料代码和浓度以获得一个唯一的字符串,然后按该字符串进行分组(见上文)。非常不雅!
    猜你喜欢
    • 2021-09-01
    • 2018-05-07
    • 1970-01-01
    • 1970-01-01
    • 2014-03-17
    • 1970-01-01
    • 2021-01-14
    • 2022-08-19
    • 2018-07-30
    相关资源
    最近更新 更多