union не работает должным образом в PostgreSQL - PullRequest
0 голосов
/ 27 сентября 2018

У меня есть запрос объединения:

(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: ОШИБКА: столбец "диалогов.createatutc "должен появиться в предложении GROUP BY или использоваться в статистической функции`

Однако, если я запускаю их по отдельности, они запускаются правильно, в этом случае createatutc - поле метки времени

Ответы [ 4 ]

0 голосов
/ 27 сентября 2018

С помощью @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 |
+ -----+----+-----------+
0 голосов
/ 27 сентября 2018

Прежде всего: я удивлен, что отдельные запросы выполняются.Вы не сможете использовать имя столбца псевдонима в HAVING, поскольку HAVING встречается до SELECT.

С UNION вы удаляете дубликаты.Таким образом, вы подсчитали месяцы, когда количество постов было точно таким же, как и не постов, только половина.Это то, что вы после?Кажется странным.

В любом случае, с вашим запросом вы получите несколько строк результатов, и вы не сможете определить, какие из них предназначены для постов, а какие для не-постов.

(И просто таквы знаете: если тип может быть нулевым, это не будет учитываться ни в одной строке, потому что неизвестное значение 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;

Вы можете сделать это без подзапросов (производных таблиц), но тогда выприходится повторять одни и те же выражения снова и снова.

0 голосов
/ 27 сентября 2018

Выполните извлечение 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
0 голосов
/ 27 сентября 2018

Удалить имя столбца псевдонима из группы, как показано ниже

   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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...