联合无法在PostgreSQL中按预期工作

时间:2018-09-27 05:31:11

标签: sql postgresql group-by

我有一个联合查询:

(SELECT
    to_char(createdatutc,'YYYY') as "Yr",
    to_char(createdatutc,'MM') as "Mh",
    count(postid) as Freq
FROM conversations
WHERE type = 'Post'
GROUP BY Yr, Mh
HAVING Yr = '2018')
UNION
(SELECT
    to_char(createdatutc,'YYYY') as "Yr",
    to_char(createdatutc,'MM') as "Mh",
    count(postid) as Freq
FROM conversations
WHERE type <> 'Post'
GROUP BY Yr, Mh having Yr = '2018')
ORDER BY  Yr, Mh

在执行时抛出以下错误:

  

org.postgresql.util.PSQLException:错误:“ conversations.createdatutc”列必须出现在GROUP BY子句中或在聚合函数中使用。

但是,如果我分别运行它们,它们将正常运行,则createdatutc是一个时间戳字段

4 个答案:

答案 0 :(得分:2)

在派生表中进行to_char提取等操作,group by其结果:

select "Yr", "Mh", count(postid), type
from
(
    SELECT
        to_char(createdatutc,'YYYY') as "Yr",
        to_char(createdatutc,'MM') as "Mh",
        postid,
        case when type = 'Post' then 'Post' else 'NotPost' end type
    FROM conversations
) dt
where "Yr" = 2018
group by  "Yr", "Mh", type

答案 1 :(得分:0)

按如下所示从分组中删除别名列名称

   select * from (
    (
    Select EXTRACT(Year FROM createdatutc::date) as "Yr",
     EXTRACT(MONTH FROM createdatutc::date) as "Mh",
    count(postid) as Freq 
     from conversations 
    where type = 'Post' 
    group by
     EXTRACT(Year FROM createdatutc::date), EXTRACT(MONTH FROM createdatutc::date) 
    having EXTRACT(Year FROM createdatutc::date) = 2018)
     union 
    (Select to_char(createdatutc,'YYYY') as "Yr",
     to_char(createdatutc,'MM') as "Mh", count(postid) as Freq 
    from conversations where type <> 'Post' 
    group by EXTRACT(Year FROM createdatutc::date), EXTRACT(MONTH FROM createdatutc::date)
 having EXTRACT(Year FROM createdatutc::date) = 2018)
) as t
order by  Yr, Mh

答案 2 :(得分:0)

首先:我很惊讶单个查询的运行。您不应该在HAVING中使用别名列名称,因为HAVING出现在SELECT之前。

使用UNION,您将删除重复项。因此,您算出的月份中,与非职位只有一半的职位数量完全相同。这是你所追求的吗?看起来很奇怪。

无论如何,通过您的查询,您将获得多个结果行,并且您将无法分辨出哪些是帖子,哪些是非帖子。

(而且,您知道:如果type可以为null,则不会在任何行中进行计数,因为NULL为未知值既不等于也不等于'Post'。)

有两种写查询的方法:

每月一次,输入

SELECT yr, mh, tp, COUNT(*)
FROM
(
  SELECT
    TO_CHAR(createdatutc, 'YYYY') AS yr,
    TO_CHAR(createdatutc, 'MM') AS mh,
    CASE WHEN type = 'Post' THEN 'Post' ELSE 'other' END AS tp
  FROM conversations
  WHERE EXTRACT(YEAR FROM createdatutc) = 2018
) yr2018
GROUP BY yr, mh, tp
ORDER BY yr, mh, tp;

每月一排

SELECT
  yr, mh,
  COUNT(CASE WHEN type = 'Post' THEN 1 END) AS count_posts,
  COUNT(CASE WHEN type <> 'Post' THEN 1 END) AS count_nonposts
FROM
(
  SELECT
    TO_CHAR(createdatutc, 'YYYY') AS yr,
    TO_CHAR(createdatutc, 'MM') AS mh,
    type
  FROM conversations
  WHERE EXTRACT(YEAR FROM createdatutc) = 2018
) yr2018
GROUP BY yr, mh
ORDER BY yr, mh;

您可以在没有子查询(派生表)的情况下执行此操作,但是随后您将不得不一次又一次地重复相同的表达式。

答案 3 :(得分:0)

在@zaynul和@Thorsten的帮助下,我如下修改了查询

select 
  yr,
  mh,
  sum(freq)
from 
(
  (
    Select 
      to_char(createdatutc,'YYYY') as "Yr",
      to_char(createdatutc,'MM') as "Mh",
      count(postid) as Freq from conversations where type = 'Post'
    group by 
      to_char(createdatutc,'YYYY'),
      to_char(createdatutc,'MM')
    having to_char(createdatutc,'YYYY') = '2018'
  ) 
  union 
  (
    Select
      to_char(createdatutc,'YYYY') as "Yr",
      to_char(createdatutc,'MM') as "Mh", 
      count(postid) as Freq 
    from conversations where type <> 'Post'
    group by 
      to_char(createdatutc,'YYYY'), 
      to_char(createdatutc,'MM') 
    having to_char(createdatutc,'YYYY') = '2018'
  )
) as t 
group by yr, Mh 
order by Yr, Mh 

为我成功的诀窍,谢谢大家的帮助和支持在此处输入代码

样本数据:

+ -------+--------------+------+
| postid | createdatutc | type |
+ -------+--------------+------+
|      1 | 2018-01-01   | Post |
|      2 | 2018-01-02   | Nope |
|      3 | 2018-01-03   | Njet |
|      4 | 2018-01-04   | Nada |
|      5 | 2018-02-01   | Post |
|      6 | 2018-02-02   | Post |
|      7 | 2018-02-03   | Post |
|      8 | 2018-02-04   | Nada |
|      9 | 2018-03-01   | Post |
|     10 | 2018-03-02   | Post |
|     11 | 2018-03-03   | Nope |
|     12 | 2018-03-04   | Nada |
+ -------+--------------+------+

结果:

+ -----+----+-----------+
| yr   | mh | sum(freq) |
+ -----+----+-----------+
| 2018 | 01 |         4 |
| 2018 | 02 |         4 |
| 2018 | 03 |         2 |
+ -----+----+-----------+