(PostgreSQL)中的案例陈述COUNT(9.3)

时间:2016-02-23 13:49:41

标签: sql postgresql

首先,这是一个课程作业问题,所以我不是在寻找一个完整的答案,只是一个提示:)

我有一个" monarch"存储名称,房屋(?),加入,加冕(?)的数据库,用于跟踪君主(包括总理)。房屋和加冕礼只适用于君主,如果君主是总理,则归还无效。 它看起来如下:

table

我需要编写一个psql查询来返回该计划(众议院,第十七,十八,十九,二十),列出在17,18,19和20年加入王位的每个王室的君主数量几个世纪,并有一个问题,作为我的THEN查询添加什么。

修改 谢谢你的建议!我现在对我的查询做了一些更改:

 SELECT  house,
         TO_CHAR(accession, 'YYYY' ) AS accession_year,
         COUNT(CASE WHEN accession_year BETWEEN 1601 AND 1700 THEN name END) AS seventeenth,
         COUNT(CASE WHEN accession_year BETWEEN 1701 AND 1800 THEN name END) AS eighteenth,
         COUNT(CASE WHEN accession_year BETWEEN 1801 AND 1900 THEN name END) AS nineteenth,
         COUNT(CASE WHEN accession_year BETWEEN 1901 AND 2000 THEN name END) AS twentieth,
  FROM monarch
  WHERE house IS NOT NULL
  GROUP BY house
  ;

现在psql告诉我accession_year不存在。我不想在CASE语句中使用完整的加入日期。我怎样才能在查询中使用我的TO_CHAR?

2 个答案:

答案 0 :(得分:1)

评估单个SELECT子句中的每个表达式"好像"它与同一子句中的所有其他表达式并行计算。因此,您不允许在它们之间存在任何依赖关系,因为在开始时没有可用的结果值。

一种选择是引入子查询:

SELECT  house,
         accession_year,
         COUNT(CASE WHEN accession_year BETWEEN 1601 AND 1700 THEN name END) AS seventeenth,
         COUNT(CASE WHEN accession_year BETWEEN 1701 AND 1800 THEN name END) AS eighteenth,
         COUNT(CASE WHEN accession_year BETWEEN 1801 AND 1900 THEN name END) AS nineteenth,
         COUNT(CASE WHEN accession_year BETWEEN 1901 AND 2000 THEN name END) AS twentieth,
  FROM (
     SELECT house,name,TO_CHAR(accession, 'YYYY' ) AS accession_year
     FROM monarch
     WHERE house IS NOT NULL ) AS t
  GROUP BY house
  ;

现在,您有两个单独的SELECT子句,外部的 允许依赖于内部计算的值。

答案 1 :(得分:1)

您可以使用子选择或CTE来SELECT(或仅使用)计算列,但在某些更简单的情况下(如您的),LATERAL join更具可读性:

SELECT   house,
         COUNT(CASE WHEN accession_century = 17 THEN 1 END) AS seventeenth,
         COUNT(CASE WHEN accession_century = 18 THEN 1 END) AS eighteenth,
         COUNT(CASE WHEN accession_century = 19 THEN 1 END) AS nineteenth,
         COUNT(CASE WHEN accession_century = 20 THEN 1 END) AS twentieth
FROM     monarch,
         date_part('century', accession) accession_century
WHERE    house IS NOT NULL
GROUP BY house

注意: to_char()会返回一个字符串,对查询不是很有用,请改用date_part()EXTRACT()。特别是在你的情况下:他们有能力提取你想要搜索的世纪。