将“UNION”与“IF EXISTS”一起使用

Posted

技术标签:

【中文标题】将“UNION”与“IF EXISTS”一起使用【英文标题】:Using "UNION" with "IF EXISTS" 【发布时间】:2015-08-03 19:51:01 【问题描述】:

我在 SQL Server 2008 R2 上遇到以下问题,我正在尝试对一组 UNION 使用 IF EXISTS 子句,但出现错误。

如果我单独运行查询,它们运行时没有错误,但如果我尝试使用 UNION 运行它们,它给了我错误:

消息 156,第 15 级,状态 1,第 9 行 关键字“IF”附近的语法不正确。

SELECT
    '1.5.2- Customers' as INPUT,
    count (distinct ID) as Z,
    PRO_DATE,
    Month(PRO_DATE) as P_MONTH,
    Year(PRO_DATE) as P_YEAR
FROM
    [BASE]
WHERE
    BASE.CAT_CUSTO = 'EMPLO' and
    BASE.ESTAT = 'EX'
group by
    PRO_DATE

UNION 

IF  EXISTS (
    SELECT
        '1.6- OTHER CUSTOMERS' as INPUT,
        count (distinct ID)  as Z,
        PRO_DATE,
        Month(PRO_DATE) as P_MONTH,
        Year(PRO_DATE) as P_YEAR
    FROM
        [BASE]
    WHERE
        BASE.CAT_CUSTO <> 'EMPLO'
    group by
        PRO_DATE
)  begin
SELECT
        '1.6- OTHER CUSTOMERS' as INPUT,
        count (distinct ID)  as Z,
        PRO_DATE,
        Month(PRO_DATE) as P_MONTH,
        Year(PRO_DATE) as P_YEAR
    FROM
        [BASE]
    WHERE
        BASE.CAT_CUSTO <> 'EMPLO'
    group by
        PRO_DATE

 end
ELSE
    SELECT TOP 1
        '1.6- OTHER CUSTOMERS' as INPUT,
        0 as Z,
        PRO_DATE,
        Month(PRO_DATE) as P_MONTH,
        Year(PRO_DATE) as P_YEAR
    FROM
        [BASE]

【问题讨论】:

您混淆了 T-SQL 控制流代码和 SQL 查询。不是一个不寻常的混乱,但你最好描述你想要做什么(即样本数据和期望的结果)而不是显示显然无法工作的代码。 Top 1 without order by 只是从表中随机选择一条记录。 @Magnus 是的,这也让我感到困惑。 带有“前 1”的最后一部分仅获得 1 条记录,因为如果我有 100 条,我将得到 100 条相同的结果(表中每条记录的结果) @ThatguyfromIT 你可以接受随机的PRO_DATE吗? 【参考方案1】:

你说

q1

union 

if exists(q2)

  q3

else

  q4

不起作用,但所有查询都起作用。我怀疑它查看查询,但如果是这种情况,那么只需将其更改为

if exists(q2)

  q1

  union 

  q3

else

  q1

  union 

  q4

【讨论】:

nono,就像 q1 union if exists(q2) q2 else q3 @ThatguyfromIT - 好的...我在第二个参考中调用 q2 q3 的事实与解决方案的逻辑无关。【参考方案2】:

您可以使用临时表:

SELECT
    '1.6- OTHER CUSTOMERS' as INPUT,
    count (distinct ID)  as Z,
    PRO_DATE,
    Month(PRO_DATE) as P_MONTH,
    Year(PRO_DATE) as P_YEAR
  INTO #temp
FROM
    [BASE]
WHERE
    BASE.CAT_CUSTO <> 'EMPLO'
group by
    PRO_DATE

然后

IF SELECT COUNT(*) FROM #temp > 0
BEGIN
SELECT
    '1.5.2- Customers' as INPUT,
    count (distinct ID) as Z,
    PRO_DATE,
    Month(PRO_DATE) as P_MONTH,
    Year(PRO_DATE) as P_YEAR
FROM
    [BASE]
WHERE
    BASE.CAT_CUSTO = 'EMPLO' and
    BASE.ESTAT = 'EX'
group by
    PRO_DATE

UNION 

SELECT
    '1.6- OTHER CUSTOMERS' as INPUT,
    count (distinct ID)  as Z,
    PRO_DATE,
    Month(PRO_DATE) as P_MONTH,
    Year(PRO_DATE) as P_YEAR
FROM
    [BASE]
WHERE
    BASE.CAT_CUSTO <> 'EMPLO'
group by
    PRO_DATE

 end

ELSE

SELECT
    '1.5.2- Customers' as INPUT,
    count (distinct ID) as Z,
    PRO_DATE,
    Month(PRO_DATE) as P_MONTH,
    Year(PRO_DATE) as P_YEAR
FROM
    [BASE]
WHERE
    BASE.CAT_CUSTO = 'EMPLO' and
    BASE.ESTAT = 'EX'
group by
    PRO_DATE

UNION 

SELECT TOP 1
    '1.6- OTHER CUSTOMERS' as INPUT,
    0 as Z,
    PRO_DATE,
    Month(PRO_DATE) as P_MONTH,
    Year(PRO_DATE) as P_YEAR
FROM
    [BASE]

【讨论】:

听起来不错,让我试一试,因为我希望编辑 ssis 以分开执行这些步骤【参考方案3】:
DECLARE @chk NVARCHAR(1)='B';
/** change @chk as 'C' to see the result**/
WITH T1 AS(SELECT * FROM(VALUES('A',1))a(F1,F2)
),T2 AS(SELECT * FROM(VALUES('B',2))a(F1,F2)
),T3 AS(SELECT * FROM(VALUES('C',3))a(F1,F2)
),CHK AS(SELECT CASE WHEN EXISTS(SELECT * FROM T2 WHERE F1=@chk) THEN 'B' ELSE 'C' END[chk_f]
) SELECT * FROM T1 UNION SELECT T2.* FROM T2,CHK WHERE chk_f='B' UNION SELECT T3.* FROM T3,CHK WHERE chk_f='C'

【讨论】:

请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助、质量更好,并且更有可能吸引投票

以上是关于将“UNION”与“IF EXISTS”一起使用的主要内容,如果未能解决你的问题,请参考以下文章

将 READ UNCOMMITTED 与 UNION ALL 一起使用

SQL Server:如何将 UNION 与两个都有 WHERE 子句的查询一起使用?

如何让多个不同的SQL语句一起执行?

我可以在 MySQL 中将 Distinct 与 Union All 一起使用吗?

Union与Union All的区别

与 UNION 一起使用时,对每个 SQL Server 查询都不起作用的排序