困难的postgreSQL查询

时间:2017-08-02 15:08:47

标签: sql postgresql

我有两个表格

用户

    id |  name  | sex | birth
    ---+--------+-----+------
    1  |  User1 | 0   | 2007-07-12
    2  |  User2 | 0   | 1988-05-10
    3  |  User3 | 1   | 2000-01-11
    4  |  User4 | 1   | 1999-10-10

另一个表格

顺序

id | user_id | price | order_date  
---------------------------------------------
1  | 3       |  5    | 2017-07-10 08:01:00.000000
2  | 3       |  6    | 2017-07-11 09:01:00.000000
3  | 1       |  8    | 2017-07-12 10:01:00.000000
4  | 2       |  10   | 2017-07-13 11:01:00.000000
5  | 4       |  100  | 2017-07-14 12:01:00.000000
6  |         |  58   | 2017-07-15 13:01:00.000000

我需要像这样的结果表

顺序

          |age    |   men_pr | women_pr| 
          |-----------------------------
          |<18    |     8    |         | 
          |18-50  |     10   | 111     |  
          |>50    |          |         |  

按日期渐变

WHERE  
      order.order_date  >= '2017-07-01 08:01:00.000000'
      AND order.order_date  <= '2017-07-15 08:01:00.000000'

1 个答案:

答案 0 :(得分:1)

首先,您希望将出生日期转换为年龄类别:

SELECT id, 
(case when date_part('year',age(birth)) < 18 then '<18' 
      when date_part('year',age(birth)) > 50 then '>50' 
      else '18-50' end) as 
age, sex from g_user;

将导致此:

id |  age  | sex
----+-------+-----
  1 | <18   |   0
  2 | 18-50 |   0
  3 | <18   |   1
  4 | <18   |   1
(4 rows)

我们将在内部查询中使用它,以便我们以后可以按年龄类别进行分组。接下来我们需要一个包含所有年龄类别的表(因为我们在输出中需要它,但我们没有超过50年的任何用户):

select '<18' as age union select '18-50' union select '>50';

现在把它们放在一起,然后根据性别总结价格:

select a.age, 
       nullif(sum(case when sex = 0 then price else 0 end),0) as men_pr, 
       nullif(sum(case when sex = 1 then price else 0 end),0) as women_pr
from (select '<18' as age union select '18-50' union select '>50' ) as a 
left join (SELECT id, (case when date_part('year',age(birth)) < 18 then '<18' 
      when date_part('year',age(birth)) > 50 then '>50' else '18-50' end) as 
age, sex from g_user) u on a.age = u.age
left join g_order on u.id = user_id
group by a.age;

我们需要在此使用左连接,以确保所有类别都显示出关注度,或者数据中是否存在该年龄段的用户。

这是结果

  age  | men_pr  | women_pr
-------+---------+----------
 <18   |       8 |      111
 18-50 |      10 |
 >50   |         |
(3 rows)