繁体   English   中英

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

[英]union not working as expected in PostgreSQL

我有一个联合查询:

(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是一个时间戳字段

在派生表中进行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

从group删除别名列名称,如下所示

   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

首先:我很惊讶单个查询的运行。 您不应在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;

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

在@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 |
+ -----+----+-----------+

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM