使用ORDER BY订购年龄组' (在chartio中使用postgresql)

时间:2014-08-15 07:40:44

标签: sql postgresql

我正在显示某些年龄组中的用户数量。我使用Chartio,所以我有一个图形输出。我的问题:输出的方向是列的顺序。我希望我的年龄组(以及他们的数量)按照您的逻辑期望排列:从年轻到年老,最后“没有给出信息”。但我不能按字母顺序排序,这会弄乱桌子。我的工作是为Ordering添加另一列(数字von 1到n,在该列上使用ORDER BY,然后使该列不可见) - 请参阅下面的代码。但是我正在寻找一种更好的方法来做到这一点;要么(1)有更好的方法来使列按顺序排列,或(2)找到一种方法使计数更好,所以我不必担心排序。

 SELECT "tmp"."type" AS "Type",
        count("tmp"."type") AS "Amount",
        "tmp"."order" AS "Order"
FROM 
(SELECT "ci0"."id" AS "Id",
        "us0"."date_of_birth" AS "Date_of_Birth",
        "us0"."last_seen_at" AS "Last_seen_at",
        "us0"."username" AS "username",
        "us0"."email" AS "email",
        CASE 
  WHEN DATE_PART('year', now()) - DATE_PART('year', "us0"."date_of_birth") >= 75
    THEN '75 years or older'
  WHEN DATE_PART('year', now()) - DATE_PART('year', "us0"."date_of_birth") >= 65
    THEN '65-74 years old'
  WHEN DATE_PART('year', now()) - DATE_PART('year', "us0"."date_of_birth") >= 55
    THEN '55-64 years old'
  WHEN DATE_PART('year', now()) - DATE_PART('year', "us0"."date_of_birth") >= 45
    THEN '45-54 years old'
  WHEN DATE_PART('year', now()) - DATE_PART('year', "us0"."date_of_birth") >= 35
    THEN '35-44 years old'
  WHEN DATE_PART('year', now()) - DATE_PART('year', "us0"."date_of_birth") >= 25
    THEN '25-34 years old'
  WHEN DATE_PART('year', now()) - DATE_PART('year', "us0"."date_of_birth") >= 18
    THEN '18-24 years old'
  WHEN DATE_PART('year', now()) - DATE_PART('year', "us0"."date_of_birth") >= 12
    THEN '12-17 years old'
  WHEN DATE_PART('year', now()) - DATE_PART('year', "us0"."date_of_birth") < 12
    THEN 'under 12 years old'
  ELSE 'No Birthdate given'
    END AS "type",
        CASE 
  WHEN DATE_PART('year', now()) - DATE_PART('year', "us0"."date_of_birth") >= 75
    THEN 9
  WHEN DATE_PART('year', now()) - DATE_PART('year', "us0"."date_of_birth") >= 65
    THEN 8
  WHEN DATE_PART('year', now()) - DATE_PART('year', "us0"."date_of_birth") >= 55
    THEN 7
  WHEN DATE_PART('year', now()) - DATE_PART('year', "us0"."date_of_birth") >= 45
    THEN 6
  WHEN DATE_PART('year', now()) - DATE_PART('year', "us0"."date_of_birth") >= 35
    THEN 5
  WHEN DATE_PART('year', now()) - DATE_PART('year', "us0"."date_of_birth") >= 25
    THEN 4
  WHEN DATE_PART('year', now()) - DATE_PART('year', "us0"."date_of_birth") >= 18
    THEN 3
  WHEN DATE_PART('year', now()) - DATE_PART('year', "us0"."date_of_birth") >= 12
    THEN 2
  WHEN DATE_PART('year', now()) - DATE_PART('year', "us0"."date_of_birth") < 12
    THEN 1
  ELSE 10
    END AS "order"

FROM "public"."users" AS "us0"
INNER JOIN "public"."chat_infos" AS "ci0"
ON "ci0"."user_id" = "us0"."id"  
  WHERE ("us0"."last_seen_at" BETWEEN NOW() - INTERVAL '28 DAY' AND NOW())
  ) AS "tmp"

GROUP BY "type", "Order"
ORDER BY "Order"
LIMIT 1000;

2 个答案:

答案 0 :(得分:0)

您可以在小型查找表中输入age-as-text信息,使用date_part逻辑连接到该信息,然后在文本字段中进行排序。

e.g。

你的查找表会有

id
age_text_description
age_from
age_to

您的加入形式为:

...on DATE_PART('year', now()) - DATE_PART('year', "us0"."date_of_birth")
between age_from and age_to

答案 1 :(得分:0)

SQL Fiddle

with age_groups(ag, description) as (
    values
    (int4range(0, 11, '[]'), 'under 12 years old'),
    (int4range(12, 17, '[]'), '12-17 years old'),
    (int4range(18, 24, '[]'), '18-24 years old'),
    (int4range(25, 34, '[]'), '25-34 years old'),
    (int4range(35, 44, '[]'), '35-44 years old'),
    (int4range(45, 54, '[]'), '45-54 years old'),
    (int4range(55, 64, '[]'), '55-64 years old'),
    (int4range(65, 74, '[]'), '65-74 years old'),
    (int4range(75, 999, '[]'), '75 years or older')
)
select age_group, "Amount"
from (
    select
        ag,
        coalesce(description, 'No Birthdate given') as age_group,
        count(*) as "Amount"
    from
        (
            select (
                date_part('year', now()) - date_part('year', us0.date_of_birth)
            )::int as age
            from
                users as us0
                inner join
                chat_infos as ci0 on ci0.user_id = us0.id
            where (us0.last_seen_at between now() - interval '28 day' and now())
        ) s
        left join
        age_groups on age <@ ag
    group by 1, 2
    order by ag
) s