我可以按未知的列数进行分组吗?

时间:2012-10-04 13:05:37

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

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

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

2 个答案:

答案 0 :(得分:3)

您认为PIVOT以及更多传统的交叉表查询方法可以提前了解您想要的列数,这是正确的。此时,您需要使用一些动态SQL来获取您所追求的内容:

答案 1 :(得分:1)

部分答案,而不是理想答案: 如果您知道永远不会有超过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从中选择您的组。它不漂亮,但很清楚。我知道它首先否定了将表格标准化的全部意义!祝你好运。