Sql server 我可以按未知的列数分组吗?

Sql server 我可以按未知的列数分组吗?,sql-server,sql-server-2008,tsql,sql-server-2005,stored-procedures,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),

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

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_组:

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
因此,我们有一系列的记录,这些记录是通过染料柱进行分组的,每个染料的独特组合及其浓度都有一个独特的组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_染料,并且t_batch中的每个记录都有不同数量的t_batch_染料记录,我如何在t_组中插入记录,并为每个染料的唯一组合及其浓度提供唯一的组id,以及每个组的批次计数

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

非常感谢,

大卫

苏格兰格拉斯哥

更新:

我所做的是使用一个函数,返回一个连接的代码字符串和conc,并使用它对数据进行分组

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

假设PIVOT和更传统的跨表查询方法希望您提前知道需要多少列,这是正确的。在这一点上,您需要使用一些动态SQL来获得您想要的:


假设PIVOT和更传统的跨表查询方法希望您提前知道需要多少列,这是正确的。在这一点上,您需要使用一些动态SQL来获得您想要的:


部分答案,而不是理想答案: 如果您知道不会有超过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

然后从中选择您的组,使用所有代码1到代码20。虽然不漂亮,但很清楚。而且我知道它首先否定了规范化表格的全部意义!祝你好运。

部分答案,但不是理想答案: 如果您知道不会有超过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

然后从中选择您的组,使用所有代码1到代码20。虽然不漂亮,但很清楚。而且我知道它首先否定了规范化表格的全部意义!祝你好运。

谢谢你。我会调查你发布的链接。谢谢。我会调查你发布的链接。谢谢,文尼。恐怕可能的组合确实很大!好啊我是根据你原来的6。另一个疯狂的想法是,您可以连接一个从表中选择的变量——或者这只是Sybase?。你必须用“更新”语句来完成。因此:更新t_batch_dye set@longstring=@longstring+dye_code++convertvarchar,dye_conc+,其中batch_id=@nextbatch将为每个元素提供唯一的字符串。需要更多的工作…这就是我最终所做的。我使用了一个函数来连接染料代码和浓度,以得到一个唯一的字符串,然后按照上面的内容进行分组。非常不雅!谢谢,文尼。恐怕可能的组合确实很大!好啊我是根据你原来的6。另一个疯狂的想法是,您可以连接一个从表中选择的变量——或者这只是Sybase?。你必须用“更新”语句来完成。因此:更新t_batch_dye set@longstring=@longstring+dye_code++convertvarchar,dye_conc+,其中batch_id=@nextbatch将为每个元素提供唯一的字符串。需要更多的工作…这就是我最终所做的。我使用了一个函数来连接染料代码和浓度,以得到一个唯一的字符串,然后按照上面的内容进行分组。非常不雅!