我在Sqlserver2012中有一些问题。我有一个表格,其中包含一个文件,用于保存系统使用的信息,并用' 分隔,我想将参数设置为系统名称并查询相关信息行:
declare @System nvarchar(50)
set @System ='BPM,SEM'
SELECT *
FROM dbo.tblMeasureCatalog t1
where ( ( select Upper(value) from dbo.split(t1.System,','))
= any( select Upper(value) from dbo.split(@System,',')))
dbo.split
是一个以分隔行返回系统的函数
答案 0 :(得分:2)
忘记在关系数据库中存储分隔列表的第二个是令人憎恶的,你可以使用INTERSECT
和EXISTS
的组合来做到这一点,例如:
DECLARE @System NVARCHAR(50) = 'BPM,SEM';
DECLARE @tblMeasureCatalog TABLE (System VARCHAR(MAX));
INSERT @tblMeasureCatalog VALUES ('BPM,XXX'), ('BPM,SEM'), ('XXX,SEM'), ('XXX,YYY');
SELECT mc.System
FROM @tblMeasureCatalog AS mc
WHERE EXISTS
( SELECT Value
FROM dbo.Split(mc.System, ',')
INTERSECT
SELECT Value
FROM dbo.Split(@System, ',')
);
返回
System
---------
BPM,XXX
BPM,SEM
XXX,SEM
修改强>
根据您提出的“任意”问题,我假设您希望这些条款与所提供的条款匹配,根据您的评论,我现在假设您需要条款匹配所有条件的记录。这是一种非常类似的方法,但您需要使用NOT EXISTS
和EXCEPT
代替:
现在所有仍然很模糊,例如,如果你搜索“BMP,SEM”它应该返回一个“BPM,SEM,YYY”的记录,它确实包含所有搜索的条款,但它确实包含附加条款。所以你需要的方法取决于你的要求:
DECLARE @System NVARCHAR(50) = 'BPM,SEM,XXX';
DECLARE @tblMeasureCatalog TABLE (System VARCHAR(MAX));
INSERT @tblMeasureCatalog
VALUES
('BPM,XXX'), ('BPM,SEM'), ('XXX,SEM'), ('XXX,YYY'),
('SEM,BPM'), ('SEM,BPM,XXX'), ('SEM,BPM,XXX,YYY');
-- METHOD 1 - CONTAINS ALL SEARCHED TERMS BUT CAN CONTAIN ADDITIONAL TERMS
SELECT mc.System
FROM @tblMeasureCatalog AS mc
WHERE NOT EXISTS
(
SELECT Value
FROM dbo.Split(@System, ',')
EXCEPT
SELECT Value
FROM dbo.Split(mc.System, ',')
);
-- METHOD 2 - ONLY CONTAINS ITEMS WITHIN THE SEARCHED TERMS, BUT NOT
-- NECESSARILY ALL OF THEM
SELECT mc.System
FROM @tblMeasureCatalog AS mc
WHERE NOT EXISTS
( SELECT Value
FROM dbo.Split(mc.System, ',')
EXCEPT
SELECT Value
FROM dbo.Split(@System, ',')
);
-- METHOD 3 - CONTAINS ALL ITEMS IN THE SEARCHED TERMS, AND NO ADDITIONAL ITEMS
SELECT mc.System
FROM @tblMeasureCatalog AS mc
WHERE NOT EXISTS
( SELECT Value
FROM dbo.Split(@System, ',')
EXCEPT
SELECT Value
FROM dbo.Split(mc.System, ',')
)
AND LEN(mc.System) = LEN(@System);
答案 1 :(得分:1)
您的数据结构存在问题,因为您将事物列表存储在以逗号分隔的列表中。 SQL具有用于存储列表的出色数据结构。它的名称是" table"。你应该有一个联结表,每个"测量目录"和"系统"。
有时,你会遇到其他人非常糟糕的设计决策。一种解决方案是使用split()
。这是一种方法:
select mc.*
from dbo.tblMeasureCatalog mc
where exists (select 1
from dbo.split(t1.System, ',') t1s join
dbo.split(@System, ',') ss
on upper(t1s.value) = upper(ss.value)
);
答案 2 :(得分:0)
你可以试试这个:
declare @System nvarchar(50)
set @System ='BPM,SEM'
SELECT * from dbo.tblMeasureCatalog t1 inner join dbo.Split (@System ,',') B on t1.it=B.items