我有两个sql表,正在寻找一个sql查询以针对Table2.ValueDescription列中的Table1.ValueID列中的每个数值选择数据并将结果保存在Table3中
表1:
ID ValueID
1 1,12,14
2 3,5,15
3 2,6,13,16
表2:
ValueID ValueDescription
1 Motor
2 Low
3 Failed
4 New Install
5 New Item
6 Max Value
7 AC Current
8 DC Current
9 Not Reached
10 NA
11 Cutoff
12 Manual
13 Automatic
14 Device Not Found
15 Halt
16 Renew
预期结果:
表3:
ID ValueID Result
1 1,12,14 Motor,Manual,Device Not Found
2 3,5,15 Failed,New Item,Halt
3 2,6,13,16 Low,Max Value,Automatic,Renew
使用SQL Server Management Studio
这是我尝试过的查询
SELECT Table1.ValueID,
Stuff((SELECT ',' + CAST(Table2.Description AS VARCHAR(100))
FROM Table2
WHERE Table1.ValueID LIKE Table2.ValueID
FOR Xml Path('')),1,1,'')
FROM Table1
我在这里想念什么?
答案 0 :(得分:2)
如果实际上您确实在使用SQL Server 2017,则可以同时使用STRING_SPLIT和STRING_AGG函数。它们使语法非常简单。
IF OBJECT_ID('tempdb..#Table1', 'U') IS NOT NULL
DROP TABLE #Table1;
CREATE TABLE #Table1 (
ID INT NOT NULL PRIMARY KEY,
ValueID VARCHAR(50) NOT NULL
);
INSERT #Table1 (ID, ValueID) VALUES
(1, '1,12,14'),
(2, '3,5,15'),
(3, '2,6,13,16');
IF OBJECT_ID('tempdb..#Table2', 'U') IS NOT NULL
DROP TABLE #Table2;
CREATE TABLE #Table2 (
ValueID INT NOT NULL PRIMARY KEY,
ValueDescription VARCHAR(50) NOT NULL
);
INSERT #Table2(ValueID, ValueDescription) VALUES
(1, 'Motor'),
(2, 'Low'),
(3, 'Failed'),
(4, 'New Install'),
(5, 'New Item'),
(6, 'Max Value'),
(7, 'AC Current'),
(8, 'DC Current'),
(9, 'Not Reached'),
(10, 'NA'),
(11, 'Cutoff'),
(12, 'Manual'),
(13, 'Automatic'),
(14, 'Device Not Found'),
(15, 'Halt'),
(16, 'Renew');
--SELECT * FROM #Table1 t1;
--SELECT * FROM #Table2 t2;
--========================================================
SELECT
t1.ID,
t1.ValueID,
csv.Result
FROM
#Table1 t1
CROSS APPLY (
SELECT
Result = STRING_AGG(t2.ValueDescription, ',')
FROM
STRING_SPLIT(t1.ValueID, ',') ss
JOIN #Table2 t2
ON CONVERT(INT, ss.value) = t2.ValueID
) csv;
结果...
ID ValueID Result
----------- -------------- -----------------------------------
1 1,12,14 Motor,Manual,Device Not Found
2 3,5,15 Failed,New Item,Halt
3 2,6,13,16 Low,Max Value,Automatic,Renew
编辑:
-
-============================================================================
-- This is an idea that I've been kicking around for a little while now.
-- It's based on the SUSPICION that, when left to it's own devices. STRING_SPLIT
-- will always retun rows in the original order and attaching a row_number()
-- to the output, right out of the gate, will effectively serve as an "ItemNumber.
--============================================================================
SELECT
t1.ID,
t1.ValueID,
csv.Result
FROM
#Table1 t1
CROSS APPLY (
SELECT
Result = STRING_AGG(t2.ValueDescription, ',') WITHIN GROUP (ORDER BY rs.rn DESC) -- sort in the descending order for no real eason...
FROM (
SELECT
rn = ROW_NUMBER() OVER (ORDER BY (SELECT NULL)),
ValueID = CONVERT(INT, ss.value)
FROM
STRING_SPLIT(t1.ValueID, ',') ss
) rs
JOIN #Table2 t2
ON rs.ValueID = t2.ValueID
) csv;
ID ValueID Result
----------- ------------- --------------------------------
1 1,12,14 Device Not Found,Manual,Motor
2 3,5,15 Halt,New Item,Failed
3 2,6,13,16 Renew,Automatic,Max Value,Low
答案 1 :(得分:1)
这将保持正确的顺序
示例
Select A.*
,B.*
From Table1 A
Cross Apply (
Select Result = Stuff((Select ',' +B2.ValueDescription
From (
Select RetSeq = Row_Number() over (Order By (Select null))
,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>' + replace(A.ValueID,',','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
) B1
Join Table2 B2 on B1.RetVal=B2.ValueID
Order by RetSeq
For XML Path ('')),1,1,'')
) B
返回
ID ValueID Result
1 1,12,14 Motor,Manual,Device Not Found
2 3,5,15 Failed,New Item,Halt
3 2,6,13,16 Low,Max Value,Automatic,Renew
糟糕-刚刚看到你是2017年
答案 2 :(得分:1)
并没有那么漂亮,但是SQL Server 2017中的新内置函数确实使它更容易理解,并且仍然可以遵循原始列表的顺序进行设置(嗯,我什至不知道如果您打算按列表中的位置或按数字顺序进行排序(因为它们是相同的)),则应全部为整数且没有重复项:
;WITH explode(ID, ValueID, value, i) AS
(
SELECT t1.ID,
t1.ValueID,
TRY_CONVERT(int,f.value),
CHARINDEX(',' + f.value + ',', ',' + t1.ValueID + ',')
FROM dbo.Table1 t1
CROSS APPLY STRING_SPLIT(t1.ValueID, ',') AS f
)
SELECT x.ID, x.ValueID,
-- guarantee respect original order:
Result = STRING_AGG(t2.ValueDescription,',') WITHIN GROUP (ORDER BY x.i)
FROM explode AS x
INNER JOIN dbo.Table2 AS t2
ON x.value = t2.ValueID
GROUP BY x.ID, x.ValueID
ORDER BY x.ID;
如果顺序无关紧要,并且您确定ValueID
的{{1}}列表中没有重复或非整数,则要简单得多:
Table1
答案 3 :(得分:0)
你可以喜欢
SELECT *,
STUFF(
(
SELECT ',' + ValueDescription
FROM T2
WHERE ',' + T1.ValueID + ',' LIKE '%,' + CAST(T2.ValueID AS VARCHAR) + ',%'
FOR XML PATH('')
),
1, 1, ''
) ValueDescription
FROM T1;
返回:
+----+-----------+-------------------------------+
| ID | ValueID | ValueDescription |
+----+-----------+-------------------------------+
| 1 | 1,12,14 | Motor,Manual,Device Not Found |
| 2 | 3,5,15 | Failed,New Item,Halt |
| 3 | 2,6,13,16 | Low,Max Value,Automatic,Renew |
+----+-----------+-------------------------------+