我有两个表:
表1:
Number| Code | Value
-------+------+-----
Garden |A0,C2 | 100
Garden |rest | 500
House |A0,C2 | 100
House |rest | 500
表2:
|Code|
+-----+
|A0 |
|B1 |
|C2 |
|D3 |
|E4 |
我想要一个看起来像这样的表:
Number| Code | Value
-------+------+-----
Garden |A0 | 100
Garden |B1 | 500
Garden |C2 | 100
Garden |D3 | 500
Garden |E4 | 500
House |A0 | 100
House |B1 | 500
House |C2 | 100
House |D3 | 500
House |E4 | 500
有人知道我如何获得此表的SQL语句吗?
无法更改表1或表2
答案 0 :(得分:1)
您应该修复table1
,以便它不使用以逗号分隔的字符串表示的列表。为此,您应该有一个单独的表。这样做的原因很多。
假设您被某人困住了,否则它的数据模型确实非常糟糕,则可以使用join
。有几种方法。 SQL Server 2017+具有内置的string_split()
函数。
然后,您要使用cross join
生成行,并使用left join
s引入所需的值:
select n.number, t2.code, coalesce(t1.value, t1rest.value) as value
from (select distinct number from table1) n cross join
table2 t2 left join
table1 t1
on t1.number = n.number and ',' + t1.codes + ',' like '%,' + t2.code + ',%' left join
table1 t1rest
on t1rest.number = n.number and t1rest.codes = 'rest';
Here是db <>小提琴
答案 1 :(得分:1)
我不喜欢这种解决方案,因为带有JOIN
的{{1}}很丑。我强烈建议在此修复您的数据模型。您不应在表中使用定界数据,也不应使用EXISTS
之类的值来表示您想要除先前定义的值以外的所有其他值。您在此处获得的结果集是一个规范化的数据集,而这正是存储数据的方式:
'rest'
如果您不使用SQL Server 2016+,则将无法使用CREATE TABLE Table1 (Number varchar(6), --A number is a varchar?
Code varchar(50),
[Value] int);
INSERT INTO dbo.Table1 (Number,
Code,
[Value])
VALUES ('Garden','A0,C2',100),
('Garden','rest',500),
('House','A0,C2',100),
('House','rest',500);
CREATE TABLE Table2 (Code char(2));
INSERT INTO dbo.Table2 (Code)
VALUES ('A0'),
('B1'),
('C2'),
('D3'),
('E4');
GO
WITH CTE AS(
SELECT T1.Number,
SS.[value] AS Code,
T1.[Value]
FROM dbo.Table1 T1
CROSS APPLY STRING_SPLIT(T1.Code, ',') SS)
SELECT C.Number,
T2.Code,
C.[Value]
FROM CTE C
JOIN dbo.Table2 T2 ON C.Code = T2.Code
OR (C.Code = 'rest'
AND NOT EXISTS (SELECT 1
FROM CTE e
WHERE e.Number = C.Number
AND e.Code = T2.Code))
GO
DROP TABLE dbo.Table1;
DROP TABLE dbo.Table2;
。因此,我建议查找“ XML拆分器”或STRING_SPLIT
。