我正在尝试在MERGE
查询中执行查询,以便将结果从一个表拉到另一个表中。这一切都很好,除了一个小小的hickup ...
为从表中获取数据而执行的查询取决于名为@User_ID
的变量。
如果@User_ID
为NULL
,则执行子查询A,否则执行子查询B.
我遇到的问题是我不知道如何在子查询中放置IF
...我该怎么做?
这是我到目前为止所做的:
请注意,这可能有效,但由于我正在运行SQL Server 2008而不是2012(我认为),我认为IIF
功能不可用,所以我需要另一种方法来实现此 的
-- Get the relevant logins for the past 12 weeks and insert
-- them into the temporary table where the week number is the same
MERGE INTO #Number_Of_Logins AS NOL
USING (
SELECT IIF (ISNULL(@User_ID,0), (
SELECT
Year(UA.Audit_When) AS Year_Num,
DatePart(wk, UA.Audit_When) AS Week_Number,
Count(*) AS Num_Logins
FROM User_Auditing UA
WHERE Audit_Type = 'SYSLI'
AND User_ID = @User_ID
AND DATEDIFF(wk, Audit_When, GETDATE()) <= 11
GROUP BY Year(Audit_When), DatePart(wk, Audit_When)
),
(
SELECT
Year(UA.Audit_When) AS Year_Num,
DatePart(wk, UA.Audit_When) AS Week_Number,
Count(*) AS Num_Logins
FROM User_Auditing UA
JOIN User_Profiles UP ON UA.User_ID = UP.User_ID
WHERE UA.Audit_Type = 'SYSLI'
AND UP.Company_ID = @Company_ID
AND DATEDIFF(wk, UA.Audit_When, GETDATE()) <= 11
GROUP BY Year(Audit_When), DatePart(wk, UA.Audit_When)
)
)
) AS TEST
ON NOL.Week_Number = TEST.Week_Number
WHEN MATCHED THEN
UPDATE
SET Number_Of_Logins = Num_Logins;
我也尝试过使用CASE
,我收到以下错误:
在上下文中指定的非布尔类型的表达式 条件是预期的,接近'那么'。
答案 0 :(得分:1)
在不测试您的查询的情况下,存在一个明显的问题,我可以快速提出一种解决方案。
问题: CASE
表达式和IIF
函数调用使用值,而不是结果集。由于这个原因,您提出的上述方法在SQL Server 2012中也不起作用。
一种可能的解决方案:使用UNION ALL
组合您的两个可能的查询,使用不同的WHERE子句来过滤一个或另一个结果集:
-- Get the relevant logins for the past 12 weeks and insert
-- them into the temporary table where the week number is the same
MERGE INTO #Number_Of_Logins AS NOL
USING (
SELECT
Year(UA.Audit_When) AS Year_Num,
DatePart(wk, UA.Audit_When) AS Week_Number,
Count(*) AS Num_Logins
FROM User_Auditing UA
WHERE Audit_Type = 'SYSLI'
AND User_ID = @User_ID
AND DATEDIFF(wk, Audit_When, GETDATE()) <= 11
AND @User_ID Is Not Null
GROUP BY Year(Audit_When), DatePart(wk, Audit_When)
UNION ALL
SELECT
Year(UA.Audit_When) AS Year_Num,
DatePart(wk, UA.Audit_When) AS Week_Number,
Count(*) AS Num_Logins
FROM User_Auditing UA
JOIN User_Profiles UP ON UA.User_ID = UP.User_ID
WHERE UA.Audit_Type = 'SYSLI'
AND UP.Company_ID = @Company_ID
AND DATEDIFF(wk, UA.Audit_When, GETDATE()) <= 11
AND @User_ID Is Null
GROUP BY Year(Audit_When), DatePart(wk, UA.Audit_When)
)
) AS TEST
ON NOL.Week_Number = TEST.Week_Number
WHEN MATCHED THEN
UPDATE
SET Number_Of_Logins = Num_Logins;
另一个选项:有两个完全独立的MERGE语句,IF语句选择执行哪一个(更多重复的代码,但可以具有查询缓存/性能优势):
-- Get the relevant logins for the past 12 weeks and insert
-- them into the temporary table where the week number is the same
IF @User_ID IS NOT NULL
MERGE INTO #Number_Of_Logins AS NOL
USING (
SELECT Year(UA.Audit_When) AS Year_Num
,DatePart(wk, UA.Audit_When) AS Week_Number
,Count(*) AS Num_Logins
FROM User_Auditing UA
WHERE Audit_Type = 'SYSLI'
AND User_ID = @User_ID
AND DATEDIFF(wk, Audit_When, GETDATE()) <= 11
GROUP BY Year(Audit_When)
,DatePart(wk, Audit_When)
) AS TEST
ON NOL.Week_Number = TEST.Week_Number
WHEN MATCHED
THEN
UPDATE
SET Number_Of_Logins = Num_Logins;
ELSE
MERGE INTO #Number_Of_Logins AS NOL
USING (
SELECT Year(UA.Audit_When) AS Year_Num
,DatePart(wk, UA.Audit_When) AS Week_Number
,Count(*) AS Num_Logins
FROM User_Auditing UA
INNER JOIN User_Profiles UP ON UA.User_ID = UP.User_ID
WHERE UA.Audit_Type = 'SYSLI'
AND UP.Company_ID = @Company_ID
AND DATEDIFF(wk, UA.Audit_When, GETDATE()) <= 11
GROUP BY Year(Audit_When)
,DatePart(wk, UA.Audit_When)
) AS TEST
ON NOL.Week_Number = TEST.Week_Number
WHEN MATCHED
THEN
UPDATE
SET Number_Of_Logins = Num_Logins;
我可能会选择第二种选择,以获得(潜在)性能优势。
答案 1 :(得分:1)
这是您的解决方案,无需在如此高的水平上控制流量。
MERGE INTO #Number_Of_Logins AS NOL
USING (
SELECT
Year(UA.Audit_When) AS Year_Num,
DatePart(wk, UA.Audit_When) AS Week_Number,
Count(*) AS Num_Logins
FROM User_Auditing UA
LEFT OUTER JOIN User_Profiles UP ON UA.User_ID = UP.User_ID
WHERE Audit_Type = 'SYSLI'
AND ( User_ID = @User_ID
OR ( @User_ID IS NULL
AND UP.Company_ID = @Company_ID
)
)
AND DATEDIFF(wk, Audit_When, GETDATE()) <= 11
GROUP BY Year(Audit_When), DatePart(wk, Audit_When)
) AS TEST
ON NOL.Week_Number = TEST.Week_Number
WHEN MATCHED THEN
UPDATE
SET Number_Of_Logins = Num_Logins;
在这个例子中,where子句的第二个条件是: 提供了@User_ID 或者用户ID为空,公司ID匹配。
如果满足其中任何一个条件以及其他条件,则包含此记录。这应该封装您需要的所有信息,而不需要复杂的嵌套选择。