表元素
ElementsName ElementsCode
aaa 25
bbb 84
ccc 2
ddd 69
eee 158
表ElementsToCalc
Elements SerialNum
25,2 1
69 2
158,84,2 3
我有以上两个表,想通过ElementsToCalc从Elements中选择值,如下面的代码
select *
from Elements
where ElementsCode in (select Elements
from ElementsToCalc
where SerialNum = 1)
一无所获...
我认为它会像下面那样工作。
select *
from Elements
where ElementsCode in (25,2)
如何使此代码像我想要的那样工作?
答案 0 :(得分:1)
要使查询生效,可以使用以下查询。但是更好的选择是像上面的评论中那样重新设计架构。
select *
from Elements a
join ElementsToCalc b
on ','+b.Elements+',' like '%,'+cast(a.ElementsCode as varchar(100))+',%'
where b.serialnum=1
答案 1 :(得分:1)
在MS SQL Server 2016和更高版本中,您可以使用STRING_SPLIT从varchar中获取值。
示例代码段:
declare @ElementsToCalc table (SerialNum int identity(1,1) primary key, [Elements] varchar(30));
insert into @ElementsToCalc ([Elements]) values
('25,2'),
('69'),
('158,84,2');
declare @Elements table (ElementsName varchar(10), ElementsCode int);
insert into @Elements (ElementsName, ElementsCode) values
('aaa',25),
('bbb',84),
('ccc',2),
('ddd',69),
('eee',158);
with CALC as
(
select SerialNum, try_cast(value as int) as Element
from @ElementsToCalc ec
cross apply string_split([Elements],',') spl
where SerialNum = 1
)
select *
from @Elements e
where ElementsCode in (select distinct Element from CALC);
如果您的版本中没有STRING_SPLIT,则可以在CTE中使用XML技巧。
with CALC as
(
select SerialNum, x.value('.','int') as Element
from (
select SerialNum, cast('<x>'+replace([Elements],',','</x><x>')+'</x>' as XML) as XElements
from ElementsToCalc
where SerialNum = 1
) q
cross apply XElements.nodes('/x') as n(x)
)
select *
from Elements e
where ElementsCode in (select distinct Element from CALC);
答案 2 :(得分:1)
尝试一下:
CREATE FUNCTION [dbo].[tfn_Split]
(
@string VARCHAR(8000) ,
@SerialNum INT
)
RETURNS TABLE
As
Return (
SELECT str1.value , @SerialNum as SerialNum
FROM STRING_SPLIT(@string, ',') str1
)
DECLARE @ElementsToCalc TABLE (Elements nvarchar(50), SerialNum INT)
INSERT INTO @ElementsToCalc(Elements, SerialNum) VALUES('25,2',1)
INSERT INTO @ElementsToCalc(Elements, SerialNum) VALUES('69',2)
INSERT INTO @ElementsToCalc(Elements, SerialNum) VALUES('158,84,2',3)
DECLARE @Elements TABLE (ElementsName nvarchar(50), ElementsCode INT)
INSERT INTO @Elements(ElementsName, ElementsCode) VALUES('aaa',25)
INSERT INTO @Elements(ElementsName, ElementsCode) VALUES('bbb',84)
INSERT INTO @Elements(ElementsName, ElementsCode) VALUES('ccc',2)
INSERT INTO @Elements(ElementsName, ElementsCode) VALUES('ddd',69)
INSERT INTO @Elements(ElementsName, ElementsCode) VALUES('eee',158)
SELECT *
FROM @Elements
WHERE elementscode IN
( SELECT tb1.value
FROM @ElementsToCalc AS elc
CROSS apply ( SELECT spl.serialnum,
spl.value
FROM dbo.Tfn_split ( elc.elements, elc.serialnum ) spl ) tb1
WHERE elc.serialnum = 1 )
答案 3 :(得分:0)
对于您正在使用的查询,应按如下所示修改第二张表
Elements SerialNum
25 1
2 1
69 2
158 3
84 3
2 3
答案 4 :(得分:0)
尝试如下查询。
select *
from Elements E
where EXISTS (select Elements
from ElementsToCalc ETC
where ETC.SerialNum = 1
AND E.ElementsCode IN STRING_SPLIT(ETC.Elements, ','))
OR
select *
from Elements E
where EXISTS (select Elements
from ElementsToCalc ETC
where ETC.SerialNum = 1
AND Charindex(',' + ETC.Elements + ',', ',' + E.ElementsCode + ',') > 0)
答案 5 :(得分:0)
使用EXISTS
和CHARINDEX()
CREATE TABLE T1
([ElementsName] varchar(3), [ElementsCode] int);
INSERT INTO T1
([ElementsName], [ElementsCode])
VALUES
('aaa', 25),
('bbb', 84),
('ccc', 2),
('ddd', 69),
('eee', 158);
CREATE TABLE T2
([Elements] varchar(8), [SerialNum] int);
INSERT INTO T2
([Elements], [SerialNum])
VALUES
('25,2', 1),
('69', 2),
('158,84,2', 3);
SELECT *
FROM T1
WHERE EXISTS (SELECT 1
FROM T2
WHERE T2.SerialNum = 1
AND CHARINDEX(',' + CAST(T1.ElementsCode AS VARCHAR(11)) + ',',
',' + T2.Elements + ','
) > 0
);
返回:
+--------------+--------------+
| ElementsName | ElementsCode |
+--------------+--------------+
| aaa | 25 |
| ccc | 2 |
+--------------+--------------+