Sql-Server
嵌套在 STUFF 函式中的 CASE 語句中可空的 smallint 列的使用
我在編寫在 STUFF 函式中使用 CASE 語句的儲存過程時遇到問題。我認為我的問題可能與 Restricted 是可空的 smallint 有關。我嘗試將其轉換(您甚至可以將 smallint 轉換為字元串嗎?),但我仍然沒有得到預期的結果。我希望 WHEN 和 ELSE 在它們滿足我的查詢中的特定條件時結合起來,但它完全從我的結果中消除了這一行。
在 STUFF 中,如果該行是 Restricted,我想在 ItemStatus 上添加“(Restricted)”。如果不是 Restricted(0 或 NULL),我只想添加 ItemStatus。
我嘗試將 CASE 語句中的 WHEN 替換為以下內容:
WHEN CONVERT(varchar(100), ISNULL(Statuses2.Restricted, 0) ) = 0 THEN ', ' + dmStatuses2.ItemStatus + ' (Restricted)'
如果我將 WHEN 更改為:
WHEN Statuses2.Restricted IS NOT NULL THEN ', ' + dmStatuses2.ItemStatus + ' (Restricted)'
…我得到顯示的行(但只有 ItemStatus。此列應該有 2 個字元串連接,因為至少有一個 Restricted 和 non-Restricted 值)…但是一旦我添加了一個附加條件來嘗試檢查Restricted(
Restricted = 0
或Restricted = 1
)的值,我開始根本沒有得到任何結果。關於我做錯了什麼的任何想法?
SELECT StatusList --etc... FROM ( SELECT StatusList --etc... FROM ( SELECT StatusList, [Count] = ISNULL(COUNT(*), 0) --etc... FROM Items INNER JOIN ( SELECT ROW_NUMBER() OVER (PARTITION BY /* some stuff */ ) as RowNum, Statuses.*, STUFF(( SELECT CASE WHEN Statuses2.Restricted = 1 THEN ', ' + dmStatuses2.ItemStatus + ' (Restricted)' ELSE ', ' + dmStatuses2.ItemStatus END FROM Statuses Statuses2 WHERE Statuses2.StatusId = Statuses.StatusId FOR XML PATH('') ), 1, 2, '') AS StatusList FROM Statuses INNER JOIN dmStatuses ON dmStatuses.StatusId = Statuses.StatusId WHERE Statuses.TableId = @TableId ) AS Statuses2 ON Statuses2.TableId = Items.TableId AND Statuses2.EndDt IS NULL AND RowNum = 1 INNER JOIN dmStatuses dmStatuses2 ON dmStatuses2.StatusId = Statuses2.StatusId LEFT JOIN dmItems dmItems2 ON dmItems2.ItemId = Items.ItemId WHERE Items.TableId = @TableId GROUP BY Items.TableId, dmItems2.ItemId, Statuses2.StatusList ) AS ItemCounts LEFT JOIN dmItems ON dmItems.ItemId = ItemCounts.ItemId ) AS ItemCountsAndLimits WHERE ItemCountsAndLimits.[Count] > ItemCountsAndLimits.Limit
另一種創建方法
StatusList
是使用STRING_AGG
(來自 SQL Server 2017):SELECT STRING_AGG(x.status,',') FROM ( SELECT ROW_NUMBER() OVER (PARTITION BY StatusId) as RowNum, CASE WHEN Status.Rescriced = 1 THEN ItemStatus + ' (Restricted)' ELSE ItemStatus END AS Status FROM Statuses) x
以上查詢未經測試,應根據您的情況進行調整。
我相信如果你改變你的 CASE 語句來評估 a
NULL
,你應該沒問題,如下所示:CASE WHEN Statuses2.Restricted IS NULL OR Statuses2.Restricted = 0 THEN ', ' + dmStatuses2.ItemStatus ELSE ', ' + dmStatuses2.ItemStatus + ' (Restricted)' END
請注意,我評估的是
NULL
or 0 而不是 1,基本上顛倒了您的邏輯,因為這應該正確地擷取NULL
您的描述。此外,看起來您正在執行內部連接,
dmStatuses2
並且Statuses2
通過設計過濾掉所有 NULL 欄位,因此您需要將其更改為LEFT JOIN
:LEFT JOIN dmStatuses dmStatuses2 ON dmStatuses2.StatusId = Statuses2.StatusId