按2列分组后,组之间有区别

发布于 2025-02-02 21:48:55 字数 1873 浏览 1 评论 0原文

我有下表:

iddate_of_birth性别
101/01/1990男性
201/01/1961女性
301/01/1992女性
401/01/2000男性
501/01/11/1980男性
601/01/01/1990女性

作为输出,我希望每十年的男性和女性人数之间的差异:

十年_of_birthemair_minus_male
19601
1980-1
1990 -1901
2000-1,

例如,在90年代的十年中,1个男性出生,2个女性和2个女性 - > 2-1 = 1

到目前为止,我得到了:

CREATE TABLE person (
    id BIGSERIAL NOT NULL PRIMARY KEY,
    date_of_birth DATE,
    gender VARCHAR(50)
);

insert into person (id, date_of_birth, gender) values (1, '01/01/1990', 'male');
insert into person (id, date_of_birth, gender) values (2, '01/01/1961', 'female');
insert into person (id, date_of_birth, gender) values (3, '01/01/1992', 'female');
insert into person (id, date_of_birth, gender) values (4, '01/01/2000', 'male');
insert into person (id, date_of_birth, gender) values (5, '01/01/1980', 'male');
insert into person (id, date_of_birth, gender) values (6, '01/01/1990', 'female'); 

SELECT *
FROM crosstab($$
    SELECT EXTRACT(DECADE
               FROM date_of_birth) * 10 AS decade_of_birth,
       gender,
       COUNT(DISTINCT id) AS nbr_persons
FROM person
GROUP BY 1,2
  $$, $$ SELECT DISTINCT gender FROM person; $$) AS ct( decade_of_birth int, "Male" int, "Female" int);

唯一剩下的就是获得2列之间的差异。我知道我可以通过在子查询中编写并简单地提取2列,但是我想知道串扰中是否有更优雅的方式来获得所需的输出。

I have the following table:

iddate_of_birthgender
101/01/1990male
201/01/1961female
301/01/1992female
401/01/2000male
501/01/1980male
601/01/1990female

As output I want the difference between number of males and females per decade:

decade_of_birthfemale_minus_male
19601
1980-1
19901
2000-1

For example, in the decade of the 90s, 1 male was born, and 2 females --> 2-1 = 1

So far I got this:

CREATE TABLE person (
    id BIGSERIAL NOT NULL PRIMARY KEY,
    date_of_birth DATE,
    gender VARCHAR(50)
);

insert into person (id, date_of_birth, gender) values (1, '01/01/1990', 'male');
insert into person (id, date_of_birth, gender) values (2, '01/01/1961', 'female');
insert into person (id, date_of_birth, gender) values (3, '01/01/1992', 'female');
insert into person (id, date_of_birth, gender) values (4, '01/01/2000', 'male');
insert into person (id, date_of_birth, gender) values (5, '01/01/1980', 'male');
insert into person (id, date_of_birth, gender) values (6, '01/01/1990', 'female'); 

SELECT *
FROM crosstab($
    SELECT EXTRACT(DECADE
               FROM date_of_birth) * 10 AS decade_of_birth,
       gender,
       COUNT(DISTINCT id) AS nbr_persons
FROM person
GROUP BY 1,2
  $, $ SELECT DISTINCT gender FROM person; $) AS ct( decade_of_birth int, "Male" int, "Female" int);

The only thing that remains is getting the difference between the 2 columns. I know I can it by writing in a subquery and simply extract the 2 columns, but I was wondering if there is a more elegant way within the crosstab to get the desired output.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

萌梦深 2025-02-09 21:48:55
  WITH grouped_gender 
    AS (
       SELECT *
         FROM crosstab($SELECT EXTRACT(DECADE FROM date_of_birth) * 10 AS decade_of_birth,
                                gender,
                                COUNT(DISTINCT id) AS nbr_persons
                           FROM person
 
                          GROUP BY 1,2
                       $, $SELECT DISTINCT gender
                              FROM person
                           $) 
    AS ct(decade_of_birth int, 
          "Male" int, 
          "Female" int))
SELECT decade_of_birth,
       "Female" - "Male" AS female_minus_male
  FROM grouped_gender;    
  • 的人数
  • 内部查询每十年获得每个性别crosstab
  • ,将封闭的性别包裹在CTE中,从CROSSTAB访问列(找不到更优雅的解决方案)
  WITH grouped_gender 
    AS (
       SELECT *
         FROM crosstab($SELECT EXTRACT(DECADE FROM date_of_birth) * 10 AS decade_of_birth,
                                gender,
                                COUNT(DISTINCT id) AS nbr_persons
                           FROM person
 
                          GROUP BY 1,2
                       $, $SELECT DISTINCT gender
                              FROM person
                           $) 
    AS ct(decade_of_birth int, 
          "Male" int, 
          "Female" int))
SELECT decade_of_birth,
       "Female" - "Male" AS female_minus_male
  FROM grouped_gender;    
  • Inner query gets number of person per decade per gender
  • Crosstab unstacks gender
  • Wrapped in a CTE to access columns from Crosstab (couldn't find a more elegant solution)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文