是否将ID附加到多次联接的SQL表上的字段?
我有两张桌子 人 装置 以及一个将第一个连接到第二个连接三次的查询:是否将ID附加到多次联接的SQL表上的字段?,sql,sql-server,Sql,Sql Server,我有两张桌子 人 装置 以及一个将第一个连接到第二个连接三次的查询: select p.PersonId, d1.*, d2.*, d3.* from People p left join Device d1 on d1.DeviceId = p.Device1 left join Device d2 on d2.DeviceId = p.Device2 left join Device d3 on d3.DeviceId = p.Device3 PersonId | D
select p.PersonId, d1.*, d2.*, d3.* from People p
left join Device d1 on d1.DeviceId = p.Device1
left join Device d2 on d2.DeviceId = p.Device2
left join Device d3 on d3.DeviceId = p.Device3
PersonId | Device1 | Device2 | Device3 | DeviceId | Name | Description | PicklingCoefficient | DeviceId | Name | Description | PicklingCoefficient | DeviceId | Name | Description | PicklingCoefficient
这将以people+device+device+device的格式生成表头,其中设备表字段仅重复三次:
select p.PersonId, d1.*, d2.*, d3.* from People p
left join Device d1 on d1.DeviceId = p.Device1
left join Device d2 on d2.DeviceId = p.Device2
left join Device d3 on d3.DeviceId = p.Device3
PersonId | Device1 | Device2 | Device3 | DeviceId | Name | Description | PicklingCoefficient | DeviceId | Name | Description | PicklingCoefficient | DeviceId | Name | Description | PicklingCoefficient
从技术上讲,我可以构建一个字符串生成器,在提交查询之前为每个dn表生成一些唯一的名称,但是有什么方法可以简化它吗
可能通过在查询的第一行添加一些内容来提供people+device1+device2+device3的格式:
PersonId | Device1 | Device2 | Device3 | DeviceId1 | Name1 | Description1 | PicklingCoefficient1 | DeviceId2 | Name2 | Description2 | PicklingCoefficient2 | DeviceId3 | Name3 | Description3 | PicklingCoefficient3
我希望这样的事情能奏效:
select p.PersonId, d1.* + '1', d2.* + '2', d3.* + '3' from People p
这里真正的问题是你的设计,它是非规范化的。在这里,您似乎有一个多对多的关系,这意味着您实际上需要做的是规范化您的设计 您应该有另一个处理对多对多关系的表,而不是一个具有3个不同列的人的设备。简单来说,您的表格如下所示:
CREATE TABLE dbo.People (PersonID int IDENTITY PRIMARY KEY,
[Name] nvarchar(50)); --Overly simplified
GO
CREATE TABLE dbo.Device (DeviceID int IDENTITY PRIMARY KEY,
[Name] char(2),
[Description] varchar (50),
PicklingCoefficient smallint);
GO
CREATE TABLE dbo.PersonDevice (PersonID int,
DeviceID int);
ALTER TABLE dbo.PersonDevice ADD CONSTARINT PersonDevice_PK PRIMARY KEY(PersonID, DeviceID);
ALTER TABLE dbo.PersonDevice ADD CONSTRAINT PersonDevice_PersonFK FOREIGN KEY (PersonID) REFERENCES dbo.People (PersonID);
ALTER TABLE dbo.PersonDevice ADD CONSTRAINT PersonDevice_DeviceFK FOREIGN KEY (DeviceID) REFERENCES dbo.Device (DeviceID);
GO
然后插入数据,如下所示:
插入dbo.People[名称]
“Bob”和“Jayne”的价值;
插入dbo.Device[名称],[说明],PicklingCoefficient
值'AA','Whatever',1,
‘BB’,‘谁知道’,-1,
“抄送”,“诸如此类”,100;
去
-然后是设备关系
插入dbo.PersonDevicePersonID,DeviceID
值1,1,1,2,1,3,2,3;
这样就不需要多个联接,因为只有2个联接,并且没有重复的列:
挑选*
来自dbo.P
在P.PersonID=PD.PersonID上加入dbo.PersonDevice PD
在PD.DeviceID=D.DeviceID上连接dbo.deviced;
我建议您取消PIVOT并将数据放在单独的行中:
select p.PersonId, v.device_number, d.*
from People p cross apply
(values (1, p.Device1), (2, p.Device2), (3, p.Device3)
) v(device_number, device) left join
Device d
on d.DeviceId = v.device_number
order by p.PersonId, v.device_number;
您可以通过替换d1来使用别名。*作为d1.DeviceId作为DeviceId1,d1.Name作为Name1…这就是我想要避免的,因为a有很多列,b连接是动态的,所以必须手动键入所有列名@jamheadart。如果是的话,您应该向我们展示相同的动态语句,因为您很可能能够动态地实现您想要的。尽管如此,问题是,为什么您的语句是动态的?而且,您的People表有Device1、Device2等列这一事实本身就是一个设计缺陷。也许真正的解决方案是规范化您的设计。为什么每个设备不使用一行联合呢?这样就不会有重复的列名。数据最初是这样设置的。已经创建了一个视图,该视图以数据为轴心,并为所需的设备表实例动态附加单个指示符列。然后,我的工作就是使用这些指标加入到这个视图中,并用表的完整实例替换每个指标。那么,您向我们展示的并不是这里的真实情况,@jamheadart。您在问题的开头陈述我有两个表,然后显示非规范化数据。显然,首先,您没有2个表,它们也没有去模型化。告诉我们真正的问题…我知道,我不可能。实际上,我应该忽略多个连接,只是询问是否可以将字符串附加到select行中表的所有字段中。我试图提供一点背景,但现在我得到了一个我没有问的问题的答案!首先它是未插入的,一个视图将其旋转,我将加入到视图中。我的手有些打结。我将在前端构建一个字符串,分别命名每一列。@jamheadart。这里的景色可能对你没有任何好处。我要花很长时间才能把它拆开,尽量减少。在这里,我会看看我能做些什么。