如何使用 UNION 从两个查询中 return 相同数量的行?

How to return same number of row from both queries with UNION?

我有两个使用 SUM()GROUP BY 的查询。每个查询应该 return 相同的数字或行。在这种情况下,我的 SQL 在 Sybase returns 中,行分开而不是在同一行上。这是我的查询:

SELECT type_id, category_id, category_name, type_code, amount, awarded
    FROM (
        SELECT
            type_id, 
            category_id,
            category_name, 
            type_code,
            CASE 
                WHEN category_id = 1 THEN SUM(amount)
                WHEN category_id = 2 THEN SUM(amount)
                WHEN category_id = 3 THEN SUM(amount)
                WHEN category_id = 4 THEN SUM(amount)
            END AS amount,
            0 AS awarded
        FROM Table 1
        GROUP BY category_id, type_id, category_id, type_code
        UNION
        SELECT
            null AS type_id, 
            ga.grant_category_id,
            '' AS category_name, 
            null AS type_code,
            0 AS amount,
            CASE 
                WHEN t2.category_id = 1 THEN SUM(t2.awarded)
                WHEN t2.category_id = 2 THEN SUM(t2.awarded)
                WHEN t2.category_id = 3 THEN SUM(t2.awarded)
                WHEN t2.category_id = 4 THEN SUM(t2.awarded)
            END AS awarded
        FROM Table2 t2
            INNER JOIN Table3 t3
                ON t2.rec_id = t3.rec_id
        GROUP BY t2.category_id
    ) x
    GROUP BY x.category_id

查询结果如下所示:

type_id  category_id  category_name  type_code   amount   awarded
   1         2             TEST 2      REST     51804.00    0.00
   1         4             TEST 4      REST     39398.00    0.00
   1         3             TEST 3      REST     79922.00    0.00
   1         1             TEST 1      REST     70927.00    0.00
  null       1             null        null       0.00     96013.00
  null       2             null        null       0.00     78759.00
  null       3             null        null       0.00     21436.00
  null       4             null        null       0.00     74602.00

我希望输出如下所示:

 type_id  category_id  category_name  type_code   amount   awarded
   1         2             TEST 2      REST     51804.00    96013.00
   1         4             TEST 4      REST     39398.00    78759.00
   1         3             TEST 3      REST     79922.00    21436.00
   1         1             TEST 1      REST     70927.00    74602.00

如何实现这样的输出?谢谢。

这就是你想要的吗?

SELECT type_id, category_id, category_name, type_code, amount, awarded
    FROM (
        SELECT
            t1.type_id, 
            t1.category_id,
            t1.category_name, 
            t1.type_code,
            SUM(t1.amount) amount,
            SUM(t2.awarded) awarded
        FROM Table1 t1
            INNER JOIN Table2 t2
                ON t1.category_id = t2.category_id
            INNER JOIN Table3 t3
                ON t2.rec_id = t3.rec_id
        GROUP BY 
            t1.type_id, 
            t1.category_id,
            t1.category_name, 
            t1.type_code
        )    x

另外,在你的例子中,我觉得是有错误的。 不应该是这样吗? Table1Table2 的键是 category_id

type_id category_id category_name type_code 奖励金额
1 2 测试 2 休息 51804.00 78759.00
1 4 测试 4 休息 39398.00 74602.00
1 3 测试 3 休息 79922.00 21436.00
1 1 测试 1 休息 70927.00 96013.00

当@Gordon 谈到 JOIN 时,他的意思是使它们成为子查询并加入它们。以下假设任一查询可能会或可能不会返回类别:

SELECT
   Set1.type_id  --  Where this is not found in Set1, you specified null in Set2
  ,ISNULL(Set1.category_id, Set2.grant_category_id)  AS  category_id
  ,ISNULL(Set1.category_name, '')  --  Where this is not found in Set1, you specified <emptyString> in Set2
  ,Set1.type_code  --  Where this is not found in Set1, you specified null in Set2
  ,ISNULL(Set1.amount, 0)  --  Where this is not found in Set1, you specified 0 in Set2
  ,ISNULL(Set2.awarded, 0)  --  Where this is not found in Set2, you specified 0 in Set1
 FROM (
        SELECT
            type_id, 
            category_id,
            category_name, 
            type_code,
            SUM(CASE 
                    WHEN category_id between 1 and 4 THEN amount
                    ELSE 0
                END) AS amount
        FROM Table1
        GROUP BY
            type_id, 
            category_id,
            category_name, 
            type_code,
      ) Set1
 FULL OUTER JOIN (   
        SELECT
            t2.grant_category_id,
            SUM(CASE 
                    WHEN t2.category_id between 1 and 4 THEN t2.awarded
                END) AS awarded
        FROM Table2 t2
            INNER JOIN Table3 t3
                ON t2.rec_id = t3.rec_id
        GROUP BY
            t2.grant_category_id,
    ) Set2
  ON Set2.grant_category_Id = Set1.category_id

免责声明:我无法检查其语法,因此可能需要进行一些小的调试。