我正在寻找类似的东西,但无法找出编写查询的最佳方式:
SELECT DISTINCT CategoryID FROM tbl_Categories c INNER JOIN
mappingTable mp ON c.CategoryID = mp.CategoryID INNER JOIN
SubCategories sc ON mp.SubCategoryID = sc.SubCategoryID
WHERE sc.SubcategoryID IN ALL (234,245,645)
我正在构建一个动态查询,因为ID是以逗号分隔的字符串'234,245,645'传入的。但是我们都知道没有ALL这样的东西。基本上我想返回列表中包含所有子类别的所有类别。希望这是有道理的。
答案 0 :(得分:3)
你可以这样做:
SELECT CategoryID
FROM tbl_Categories c INNER JOIN
mappingTable mp ON c.CategoryID = mp.CategoryID INNER JOIN
SubCategories sc ON mp.SubCategoryID = sc.SubCategoryID
WHERE sc.SubcategoryID IN (234,245,645)
GROUP BY CategoryID
HAVING COUNT(sc.SubcategoryID)
= LEN(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE('234,245,645','0','')
, '1', '')
, '2', '')
, '3', '')
, '4', '')
, '5', '')
, '6', '')
, '7', '')
, '8', '')
, '9', '')
, ' ', '')) + 1
SELECT CategoryID
FROM tbl_Categories c INNER JOIN
mappingTable mp ON c.CategoryID = mp.CategoryID INNER JOIN
SubCategories sc ON mp.SubCategoryID = sc.SubCategoryID
WHERE sc.SubcategoryID IN (234,245,645)
GROUP BY CategoryID
HAVING COUNT(sc.SubcategoryID)
= (SELECT COUNT(DISTINCT SubcategoryID)
FROM SubCategories
WHERE SubcategoryID IN (234,245,645))
答案 1 :(得分:1)
您可以编写自己的分割功能:
CREATE FUNCTION [dbo].[Split]
(
@ItemList NVARCHAR(MAX),
@delimiter CHAR(1)
)
RETURNS @IDTable TABLE (Item VARCHAR(50))
AS
BEGIN
DECLARE @tempItemList NVARCHAR(MAX)
SET @tempItemList = @ItemList
DECLARE @i INT
DECLARE @Item NVARCHAR(4000)
SET @tempItemList = REPLACE (@tempItemList, ' ', '')
SET @i = CHARINDEX(@delimiter, @tempItemList)
WHILE (LEN(@tempItemList) > 0)
BEGIN
IF @i = 0
SET @Item = @tempItemList
ELSE
SET @Item = LEFT(@tempItemList, @i - 1)
INSERT INTO @IDTable(Item) VALUES(@Item)
IF @i = 0
SET @tempItemList = ''
ELSE
SET @tempItemList = RIGHT(@tempItemList, LEN(@tempItemList) - @i)
SET @i = CHARINDEX(@delimiter, @tempItemList)
END
RETURN
END
然后,您可以加入或选择从此表值用户定义函数返回的表。
答案 2 :(得分:1)
创建拆分函数以将CSV转换为表值,然后将表值函数连接到select子句以限制结果。见http://phelabaum.com/archive/tag/tally-table/
快速示例(要求您创建一个Tally表,详见此处http://www.sqlservercentral.com/articles/T-SQL/62867/):
CREATE FUNCTION [dbo].[TallySplit] (@Delim CHAR(1), @String VARCHAR(8000))
RETURNS TABLE AS
RETURN (
SELECT SUBSTRING(@Delim + @String + @Delim,N+1,CHARINDEX(@Delim,@Delim + @String + @Delim,N+1)-N-1) ListValue
FROM Tally
WHERE N < LEN(@Delim + @String + @Delim)
AND SUBSTRING(@Delim + @String + @Delim,N,1) = @Delim
)
GO
然后像这样编写你的选择:
DECLARE @vCatIDs varchar(max)
SET @vCatIDs = '234,245,645'
SELECT DISTINCT CategoryID FROM tbl_Categories c
INNER JOIN mappingTable mp ON c.CategoryID = mp.CategoryID
INNER JOIN SubCategories sc ON mp.SubCategoryID = sc.SubCategoryID
INNER JOIN dbo.TallySplit(',',@vCatIDs) ts ON ts.ListValue = sc.SubCategoryID
答案 3 :(得分:0)
-- Parameter string
declare @ParamStr varchar(100) = '234,245,645'
-- Convert param to xml
declare @XMLStr xml = convert(xml, '<r>'+replace(@ParamStr, ',', '</r><r>')+'</r>')
-- Store param values in table variable
declare @T table (ID int)
insert into @T
select r.value('.', 'int')
from @XMLStr.nodes('r') r(r)
-- Get the number of parameters
declare @ParamCount int = (select count(*) from @T)
-- Get the categoryids
select CategoryID
from mappingTable
where SubCategoryID in (select id from @T)
group by CategoryID
having count(CategoryID) = @ParamCount
答案 4 :(得分:0)
DECLARE @Delimitedtext varchar(max);
DECLARE @Delimiter char(1);
SET @Delimitedtext = '234,245,645,';
SET @Delimiter = ',';
;WITH Strings(s, r)
AS
(
SELECT
SUBSTRING(@Delimitedtext,1, CHARINDEX(@Delimiter, @Delimitedtext)-1) s,
SUBSTRING(@Delimitedtext,CHARINDEX(@Delimiter, @Delimitedtext)+1, len(@Delimitedtext)) r
UNION ALL
SELECT
SUBSTRING(r,1, CHARINDEX(@Delimiter, r)-1) s,
SUBSTRING(r,CHARINDEX(@Delimiter, r)+1, len(r)) r
FROM Strings
WHERE
CHARINDEX(@Delimiter, r) > 0
)
SELECT CategoryId
FROM (
SELECT c.CategoryID
FROM tbl_Categories c
JOIN mappingTable mp
ON c.CategoryID = mp.CategoryID
JOIN SubCategories sc
ON mp.SubCategoryID = sc.SubCategoryID
WHERE sc.SubcategoryID IN (SELECT s FROM Strings)
) x
GROUP BY CategoryId
HAVING COUNT(*) = (SELECT count(*) FROM Strings)
来自here的字符串拆分副本。 请注意,您需要一个尾随','。
string-split的其他实现可能对您更好,但这显示了如何处理'ALL'条件。
答案 5 :(得分:-1)
不确定你的问题是不是真的那么有点不清楚。
DECLARE @SQL NVARCHAR(MAX)
DECLARE @IDs NVARCHAR(MAX)
SET @IDs = '234,245,645'
SET @SQL = 'SELECT DISTINCT CategoryID FROM tbl_Categories c INNER JOIN
mappingTable mp ON c.CategoryID = mp.CategoryID INNER JOIN
SubCategories sc ON mp.SubCategoryID = sc.SubCategoryID
WHERE sc.SubcategoryID IN (' + @IDs + ')'
exec (@sql)