環境:Sql Server 2008另一種方法來寫這個sql
有一列包含逗號分隔值的行。
即使單個產品存在於該csv中,該如何獲取該行。
這是我如何做到的,但只是想知道是否有另一種方式來寫它?
SELECT * FROM REWARDS
WHERE ProductCsv like '%banana%'
or ProductCsv like '%strawberry%'
or ProductCsv like '%orange%'
環境:Sql Server 2008另一種方法來寫這個sql
有一列包含逗號分隔值的行。
即使單個產品存在於該csv中,該如何獲取該行。
這是我如何做到的,但只是想知道是否有另一種方式來寫它?
SELECT * FROM REWARDS
WHERE ProductCsv like '%banana%'
or ProductCsv like '%strawberry%'
or ProductCsv like '%orange%'
您當前的曲ery似乎並沒有準確地捕捉到你想要的結果。如果我們有這樣一排:
bananaberry cream pie,strawberry shortcake,orange juice
這應該與您的查詢匹配嗎?我認爲這將是更準確:
WHERE ',' + ProductCsv + ',' LIKE '%,banana,%'
OR ',' + ProductCsv + ',' LIKE '%,strawberry,%'
OR ',' + ProductCsv + ',' LIKE '%,orange,%'
如果你只是想找到一個項目,這可能是更有效的:
WHERE ',' + ProductCsv + ',' LIKE '%,banana,%'
你可能想使用拆分功能。例如:
CREATE FUNCTION dbo.SplitStrings_XML
(
@List NVARCHAR(MAX),
@Delim NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT Item = y.i.value('(./text())[1]', 'nvarchar(4000)')
FROM
(
SELECT x = CONVERT(XML, '<i>' + REPLACE(@List, @Delim, '</i><i>')
+ '</i>').query('.')
) AS a CROSS APPLY x.nodes('i') AS y(i)
);
GO
所以,現在你可以說:
SELECT * FROM dbo.REWARDS AS r
WHERE EXISTS
(
SELECT 1 FROM dbo.REWARDS AS r2
CROSS APPLY dbo.SplitStrings_XML(r2.ProductCsv, ',') AS x
WHERE x.Item IN ('orange','strawberry','banana')
AND r2.[key] = r.[key]
);
或者更簡單地說:
SELECT DISTINCT r.ProductCsv --, other columns
FROM dbo.REWARDS AS r
CROSS APPLY dbo.SplitStrings_XML(r.ProductCsv, ',') AS x
WHERE x.Item IN ('orange','strawberry','banana');
的XML的方法是依賴於各種串的脆可以存儲在表中,但有很多選擇(包括通過TVP傳遞你的設置,而不是作爲一個列表或單獨的值)。有關拆分功能的一些更深層的背景看這些博客文章:
http://www.sqlperformance.com/2012/07/t-sql-queries/split-strings
http://www.sqlperformance.com/2012/08/t-sql-queries/splitting-strings-follow-up
http://www.sqlperformance.com/2012/08/t-sql-queries/splitting-strings-now-with-less-t-sql
這一切說,我不知道這是任何比你有什麼更好的現在。
你可以使用分割功能(周圍有很多在網絡上),以ProductsCsv分成獨立的元素,然後進行比較,對香蕉,草莓等
理想情況下,你會不會保存CSV數據在一列中,但是有一個單獨的表。
在使用一起來看看下面的例子XML
DECLARE @Table TABLE(
CommaList VARCHAR(MAX)
)
INSERT INTO @Table SELECT 'banana,test,hello'
INSERT INTO @Table SELECT 'homer,banana,test,hello'
INSERT INTO @Table SELECT 'homer,banana'
INSERT INTO @Table SELECT '1,2,3'
;WITH XMLValues AS (
SELECT *,
CAST('<d>' + REPLACE(CommaList, ',', '</d><d>') + '</d>' AS XML) XMLValue
FROM @Table t
)
, SplitValues AS (
SELECT xv.*,
T2.Loc.value('.','VARCHAR(MAX)') SplitValue
FROM XMLValues xv
CROSS APPLY XMLValue.nodes('/d') as T2(Loc)
)
SELECT DISTINCT
CommaList
FROM SplitValues
WHERE SplitValue = 'banana'
nodes() Method (xml Data Type)
你可以存儲所有的值在表中進行比較
DECLARE @Product_list TABLE(
products VARCHAR(50)
)
Insert into @Product_list values
('banana'),
('strawberry'),
('orange')
SELECT * FROM REWARDS
join @Product_list
on ProductCsv like '%'+products+'%'