如果我没有在CASE
子句中添加HAVING u.urlid in (SELECT ... )
语句,我有一个返回正确数据的SQL Server 2008 R2查询。
基本上,如果变量HAVING
@IDList = '0'
部分中的所有内容
下面的语句在@IDList
子句中由HAVING u.urlid in
过滤并按预期工作,但我需要在HAVING
子句中添加一些返回所有数据的内容FROM urlcat inner join URL ON URLCat.URLID = URL.URLID
如果@IDList = '0'
。
declare @IDList NVARCHAR(MAX) = '0'
declare @Count INTEGER = 1
declare @RowIndex INTEGER = 0
declare @PageSize INTEGER = 1000000
declare @wordList NVARCHAR(MAX) = ''
Set @IDList = '110713'
Set @wordList = 'nova'
SET NOCOUNT ON;
SELECT t2.URLID, t2.CategorySummary, t2.Title, t2.[Description], t2.URL
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY COUNT(ws.equiv_word)) AS [ROW_NUMBER],
u.URLID, CategorySummary = dbo.SQL_CLR_Aggregate(ws.word + ', ' + CAST(ws.[order] AS NVARCHAR) ),
u.Title, u.[Description], u.URL
FROM URLCat uc inner join word_senses ws ON uc.CatID = ws.word_sense inner join URL u ON uc.URLID = u.URLID
GROUP BY u.urlid, u.Title, u.[Description], u.URL
-- NOTE: This is the part I'm having issues with
HAVING u.urlid in
(
SELECT URLCat.URLID
FROM urlcat inner join URL ON URLCat.URLID = URL.URLID
WHERE CatID in (SELECT * FROM dbo.bigintlist_to_tbl(@IDList))
GROUP BY urlcat.urlid
HAVING COUNT(DISTINCT catid)=@Count)
)
AS t2
WHERE t2.[ROW_NUMBER] BETWEEN @RowIndex + 1 AND @RowIndex + @PageSize AND
(@wordList = '' OR (t2.Title like '%' + @wordList + '%' OR t2.Description like '%' + @wordList + '%'))
ORDER BY t2.[ROW_NUMBER]
我已经尝试了以下case语句,我将其添加到HAVING
子句中,但我会这样做:
HAVING u.urlid in
(
CASE WHEN @IDList = '0' THEN u.urlid
ELSE
(SELECT URLCat.URLID
FROM urlcat inner join URL ON URLCat.URLID = URL.URLID
WHERE CatID in (SELECT * FROM dbo.bigintlist_to_tbl(@IDList))
GROUP BY urlcat.urlid
HAVING COUNT(DISTINCT catid)=@Count) END
)
) AS t2
但是,当我添加此CASE
语句时,它会给我一个错误:
Msg 512,Level 16,State 1,Line 15
子查询返回的值超过1。当子查询遵循=,!=,<,< =,>,> =或子查询用作表达式时,不允许这样做。
我可以确认该声明有效:
CASE
声明HAVING u.urlid in u.urlid
如果我仅(即由@IDList过滤)
HAVING u.urlid in ( SELECT URLCat.URLID FROM urlcat inner join URL ON URLCat.URLID = URL.URLID WHERE CatID in (SELECT * FROM dbo.bigintlist_to_tbl(@IDList)) GROUP BY urlcat.urlid HAVING COUNT(DISTINCT catid)=@Count))
但我需要做一个或另一个,具体取决于@IDList = '0'
任何人都可以给我一些选项或理由,说明我的CASE
声明在HAVING
条款中不起作用吗?
答案 0 :(得分:3)
case
不起作用,因为它只能产生单个值,而不是子查询的结果。
您可以在子查询中使用union来根据变量返回不同的结果:
HAVING u.urlid in (
SELECT URLCat.URLID
FROM urlcat inner join URL ON URLCat.URLID = URL.URLID
WHERE CatID in (SELECT * FROM dbo.bigintlist_to_tbl(@IDList))
GROUP BY urlcat.urlid
HAVING COUNT(DISTINCT catid)=@Count) and @IDList <> '0'
UNION ALL
SELECT u.urlid WHERE @IDList = '0'
)
答案 1 :(得分:1)
我会把它写成复合语句:
HAVING @IDList = '0' or
u.urlid in (SELECT URLCat.URLID
FROM urlcat inner join
URL
ON URLCat.URLID = URL.URLID
WHERE CatID in (SELECT * FROM dbo.bigintlist_to_tbl(@IDList))
GROUP BY urlcat.urlid
HAVING COUNT(DISTINCT catid)=@Count) END
)
) AS t2
我认为逻辑更容易遵循这种方式。
请注意,您也可以在where
子句而不是having
子句中执行此操作。