【问题标题】:Group by date for multiple tables按日期分组多个表
【发布时间】:2016-01-15 17:58:29
【问题描述】:

(我正在使用 postgres)

我有两个来自不同表的查询。每个都按日期分组。 将它们加入一个查询(UNION 或 JOIN)的最佳方法是什么? 提前致谢。

查询№1:

SELECT to_char(date,'MM') as mon,
       extract(year from date) as yyyy,
       SUM("table_1"."user_money") AS user_sum,
       SUM("table_1"."system_money") AS system_sum
FROM "table_1"
GROUP BY 1,2
ORDER BY 2,1;

查询 №1 的结果:

 mon | yyyy |     user_sum     |   system_sum    
-----+------+------------------+-----------------
 11  | 2015 |        10        |       50        
 12  | 2015 |        20        |       60        
(2 rows)

查询№2:

SELECT to_char(created_at,'MM') as mon,
       extract(year from created_at) as yyyy,
       SUM("table_2"."amount") AS payments_sum
FROM "table_2"
GROUP BY 1,2
ORDER BY 2,1;

查询 №2 的结果:

 mon | yyyy | payments_sum
-----+------+--------------     
 10  | 2015 |     500      
 11  | 2015 |     600      
 12  | 2015 |     700      
 01  | 2016 |     800      
(4 rows)

要求的结果:

 mon | yyyy | payments_sum |     user_sum     |   system_sum   
-----+------+--------------+------------------+----------------
 10  | 2015 |     500      |                  |                
 11  | 2015 |     600      |        10        |       50       
 12  | 2015 |     700      |        20        |       60      
 01  | 2016 |     800      |                  |                
(4 rows)

【问题讨论】:

  • 你在两个表中都有一个列来相互链接吗?
  • @AndreasSchmidt 不,我没有

标签: sql postgresql join group-by union


【解决方案1】:

这是另一种更特定于 PostgreSQL 的语法:

WITH query_one AS (
    SELECT 
        to_char(date,'MM') as mon,
        extract(year from date) as yyyy,
        SUM("table_1"."user_money") AS user_sum,
        SUM("table_1"."system_money") AS system_sum
    FROM 
        "table_1"
    GROUP BY 
        1,2
), query_two AS (
    SELECT 
        to_char(created_at,'MM') as mon,
        extract(year from created_at) as yyyy,
        SUM("table_2"."amount") AS payments_sum
    FROM 
        "table_2"
    GROUP BY 
        1,2
)
SELECT
    *
FROM
    query_one
    LEFT JOIN query_two USING (mon, yyyy)
ORDER BY 
    yyyy
    , mon;

USING 子句更易于使用,并防止monyyyy 在输出中出现两次,其余的只是为了清晰的视图。

【讨论】:

  • 我猜你的选择是最好的,它很完美,谢谢!因为在其他情况下是的,我们需要删除重复的列,然后对空日期使用 COALESCE 和 NULLIF
【解决方案2】:

我认为您可以将每个查询视为子查询,然后与完整的外部联接结合使用。联合可能不是你想要的。

类似这样的:

SELECT * FROM
(SELECT to_char(date,'MM') as mon,
   extract(year from date) as yyyy,
   SUM("table_1"."user_money") AS user_sum,
   SUM("table_1"."system_money") AS system_sum
FROM "table_1"
GROUP BY 1,2) AS q1
FULL OUTER JOIN 
(SELECT to_char(created_at,'MM') as mon,
   extract(year from created_at) as yyyy,
   SUM("table_2"."amount") AS payments_sum
FROM "table_2"
GROUP BY 1,2) AS q2
ON q1.mon = q2.mon AND q1.yyyy = q2.yyyy
ORDER BY 2,1

在 mon 和 yyyy 值匹配的地方加入。

【讨论】:

    【解决方案3】:

    试试这个。

    SELECT 
        to_char(date,'MM') as mon,
        extract(year from date) as yyyy,
        SUM("table_2"."amount") AS payments_sum,
        SUM("table_1"."user_money") AS user_sum,
        SUM("table_1"."system_money") AS system_sum
    FROM 
        "table_1"
    LEFT JOIN 
        "table_2" ON (to_char("table_1"."date", 'MM') = to_char("table_2"."date", 'MM') AND extract(year from "table_1"."date") = extract(year from "table_2"."date"))
    GROUP BY 1,2
    ORDER BY 2,1;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-19
      • 1970-01-01
      相关资源
      最近更新 更多