在不使用 Union ALL 的情况下添加多个 select 语句

Posted

技术标签:

【中文标题】在不使用 Union ALL 的情况下添加多个 select 语句【英文标题】:Adding multiple select statements without using Union ALL 【发布时间】:2022-01-02 04:26:06 【问题描述】:

我目前编写了一个查询,该查询使用 UNION ALL 添加多个选择语句,并返回每个选择语句中金额的总和。我的问题:有什么方法可以使这个查询更小(不是那么长)?

每个子查询中唯一改变的是用于从帐户表中获取 ID1 的 ID#

 SELECT SUM(TOTAL) TOTAL
 FROM
(
SELECT ISNULL (round(sum(signeddata),2),0)
FROM BUDGET
WHERE CATEGORY = 'ACTL'
AND TIME BETWEEN '20210100' AND '20210800'
AND CURRENCY = 'DOL'
AND DATASRC IN (
    SELECT ID1 FROM DataSrc
    WHERE ID7 = 'Logic')
AND ACCOUNT IN (
    select ID1 from Accnt
    where ID7 = 'EXPENSES')
AND ENTITY IN (
    SELECT ID1 FROM Entity
    where ID9 = 'H2')

UNION ALL

SELECT ISNULL (round(sum(signeddata),2),0)*-1
FROM BUDGET
WHERE CATEGORY = 'ACTL'
AND TIME BETWEEN '20210100' AND '20210800'
AND CURRENCY = 'DOL'
AND DATASRC IN (
    SELECT ID1 FROM DataSrc
    WHERE ID7 = 'Logic')
AND ACCOUNT IN (
    select ID1 from Accnt
    where ID7 = 'MERC')
AND ENTITY IN (
    SELECT ID1 FROM Entity
    where ID9 = 'H2')

    UNION ALL

SELECT ISNULL (round(sum(signeddata),2),0)*-1
FROM BUDGET
WHERE CATEGORY = 'ACTL'
AND TIME BETWEEN '20210100' AND '20210800'
AND CURRENCY = 'DOL'
AND DATASRC IN (
    SELECT ID1 FROM DataSrc
    WHERE ID7 = 'Logic')
AND ACCOUNT IN (
    select ID1 from Accnt
    where ID11 = 'SYNP')
AND ENTITY IN (
    SELECT ID1 FROM Entity
    where ID9 = 'H2')
) S

【问题讨论】:

使用in(...) 标准有什么问题? @Stu WET 编程,我假设 【参考方案1】:

一种想法是对 case-semijoins 求和,而不是将它们放在 FROM 子句中:

SELECT 
    ISNULL(round(sum(signeddata),2),0)
    *
    (
        case when ACCOUNT IN (select ID1 from Accnt where ID7 = 'EXPENSES') 
        then 1 else 0 end * 1
        +
        case when ACCOUNT IN (select ID1 from Accnt where ID7 = 'MERC') 
        then 1 else 0 end * (-1)
        +
        case when ACCOUNT IN (select ID1 from Accnt where ID7 = 'SYNP') 
        then 1 else 0 end * (-1)
    )
FROM BUDGET
WHERE CATEGORY = 'ACTL'
AND TIME BETWEEN '20210100' AND '20210800'
AND CURRENCY = 'DOL'
AND DATASRC IN (
    SELECT ID1 FROM DataSrc
    WHERE ID7 = 'Logic')
AND ENTITY IN (
    SELECT ID1 FROM Entity
    where ID9 = 'H2')

【讨论】:

【参考方案2】:

您可以将IN 用于ID7

始终为列指定表引用,尤其是在相关子查询中

SELECT
  ISNULL(round(sum(b.signeddata), 2), 0) TOTAL
FROM BUDGET b
WHERE b.CATEGORY = 'ACTL'
  AND b.TIME BETWEEN '20210100' AND '20210800'
  AND b.CURRENCY = 'DOL'
  AND b.DATASRC IN (
      SELECT ds.ID1 FROM DataSrc ds
      WHERE ds.ID7 = 'Logic')
  AND b.ACCOUNT IN (
      select a.ID1 from Accnt a
      where a.ID7 IN ('EXPENSES', 'MERC', 'SYNP'))
  AND b.ENTITY IN (
      SELECT e.ID1 FROM Entity e
      where e.ID9 = 'H2');

注意,如果你这样做,四舍五入会略有不同

【讨论】:

以上是关于在不使用 Union ALL 的情况下添加多个 select 语句的主要内容,如果未能解决你的问题,请参考以下文章

union和union all

UNION ALL 正在返回多个结果 [重复]

UNION 和 UNION ALL 操作符

mysql union和union all的区别

SQL union all

如何在没有 UNION ALL 的情况下查询 redshift 中的许多表?