Как группировать только по одному столбцу?

#sql #postgresql

#sql #postgresql

Вопрос:

Я хотел бы выбрать только один столбец (Failed_operation) и отдельный столбец (SN) со скрытым столбцом, как показано ниже, но я получил ошибку ОШИБКА: столбец «rw_pcba.sn » должен отображаться в предложении GROUP BY или использоваться в агрегатной функции

Я попытался удалить distinct on (SN), тогда результат появился, но результат также включает дубликат SN. Я не хочу дублировать SN в результате.

 SELECT DISTINCT ON (sn) Failed_operation
    ,count(CASE WHEN (extract(day FROM NOW() - fail_timestamp)) > 0
                AND (extract(day FROM NOW() - fail_timestamp)) <= 15 THEN 1 ELSE NULL END) AS AgingLessThan15
    ,count(CASE WHEN (extract(day FROM NOW() - fail_timestamp)) > 15
                AND (extract(day FROM NOW() - fail_timestamp)) <= 30 THEN 1 ELSE NULL END) AS Aging16To30
    ,count(CASE WHEN (extract(day FROM NOW() - fail_timestamp)) > 30
                AND (extract(day FROM NOW() - fail_timestamp)) <= 60 THEN 1 ELSE NULL END) AS Aging31To60
    ,count(CASE WHEN (extract(day FROM NOW() - fail_timestamp)) > 60 THEN 1 ELSE NULL END) AS AgingGreaterThan60
    ,count(CASE WHEN (extract(day FROM NOW() - fail_timestamp)) <= 0 THEN 1 ELSE NULL END) AS Aging0
FROM rw_pcba
WHERE rework_status = 'In-Process'
GROUP BY Failed_operation
ORDER BY sn
    ,Failed_operation ASC
  

Ответ №1:

Вам нужно сгруппировать с помощью столбца sn , когда вы используете group by, тогда это будет отличная комбинация sn и failed_operation, вам не нужно указывать distinct.

 SELECT sn, Failed_operation,
count  (case when (extract(day from NOW() - fail_timestamp)) >0 and (extract(day from NOW() - fail_timestamp))<=15 then 1 else null end) as AgingLessThan15,
count  (case when (extract(day from NOW() - fail_timestamp)) >15 and (extract(day from NOW() - fail_timestamp))<=30 then 1 else null end) as Aging16To30,
count  (case when (extract(day from NOW() - fail_timestamp)) >30 and (extract(day from NOW() - fail_timestamp))<=60 then 1 else null end) as Aging31To60,
count  (case when (extract(day from NOW() - fail_timestamp)) >60 then 1 else null end) as AgingGreaterThan60,
count  (case when (extract(day from NOW() - fail_timestamp)) <=0 then 1 else null end) as Aging0
FROM rw_pcba where rework_status='In-Process' 
GROUP by sn,Failed_operation  ORDER BY  sn,Failed_operation ASC
  

Комментарии:

1. Спасибо за код, на самом деле мне нужен только один столбец (Failed_operation), отображаемый в таблице для столбца SN, могу ли я скрыть его?

2. Требуется ли дублировать failed_operation без sn?

3. @WannisaCheamsiri Напишите внешний запрос с Failed_operation.

4. Я хотел бы подсчитать данные без дублирования SN

Ответ №2:

Вы хотите агрегировать по sn , а также failed_operation . Я также думаю, что вы можете упростить вычисление каждого столбца:

 SELECT sn, Failed_operation,
       count(*) filter (where fail_timestamp > current_date and fail_timestamp < current_date   interval '15 day') as AgingLessThan15,
       count(*) filter (where fail_timestamp > current_date   interval '15 day' and fail_timestamp < current_date   interval '30 day') as Aging16To30,
       count(*) filter (where fail_timestamp > current_date   interval '30 day' and fail_timestamp < current_date   interval '600 day') as Aging31To60,
       count(*) filter (where fail_timestamp > current_date   interval '60 day') as AgingGreaterThan60,
       count(*) filter (where fail_timestamp <= current_date) as Aging0
FROM rw_pcba
WHERE rework_status = 'In-Process'
GROUP BY sn, Failed_operation
ORDER BY sn, Failed_operation ASC;
  

Я предпочитаю прямое сравнение дат для этого типа логики, а не работать с разницей между датами. Мне просто легче следовать. Например, использование current_date вместо now() now() снимает вопрос о том, что происходит с компонентом времени в,,.

Редактировать:

В более старых версиях Postgres вы можете сформулировать это с помощью sum:

        sum( (fail_timestamp > current_date and fail_timestamp < current_date   interval '15 day')::int ) as AgingLessThan15,
  

Комментарии:

1. Я пробовал ваш код, но он не работает. Я получил ошибку ОШИБКА: синтаксическая ошибка в или около «(» СТРОКА 2: фильтр count (*) (где fail_timestamp > current_date