Postgresql COALESCE со строковыми литералами не работает должным образом - PullRequest
0 голосов
/ 30 сентября 2018

Я пытаюсь вывести и пометить итоговое значение столбца из накопительного пакета.

select coalesce(column_1, 'Total') as coalesced_value,     
sum(column_2) as column_sum
from table 
where yada yada
group by rollup(coalesced_value)
order by coalesced_value

Запрос работает нормально и генерирует итоговое значение, как и ожидалось, но значение столбца, которое я ожидаю, будет равно «Всего».'отображается как [null].

Есть хороший шанс, что, вероятно, с моей стороны, возможно, не хватает понимания, но есть и то, что COALESCE в PostgreSQL нестандартно и делает меняинтересно, действительно ли это я.

Цитата:

COALESCE для типов строк

Спецификация определяет COALESCE (X, Y) как синтаксическое преобразование в CASE WHENX НЕ НЕДЕЛЕ, ЧЕМ X ДАЛЕЕ Y END (остается открытым вопрос о том, действительно ли X оценивается дважды, не допуская недетерминированных выражений или выражений с побочными эффектами в этом контексте).Следствием этого является то, что применяются довольно странные правила для пустых тестов типов строк.PostgreSQL применяет к X только тест «не является нулевым значением». Соответственно, если X - это значение строки, содержащее нулевые столбцы, PostgreSQL вернет X, в то время как спецификация потребует возврата Y.

(Прекрасное объяснение, верно?)

Я также натолкнулся на некоторую информацию, которая указывает на то, что типы данных COALESCE должны совпадать, в противном случае функция молча завершается сбоем.(!)

Я ожидаю, что строковый литерал 'Total' будет интерпретирован как varchar, а column_1 определен в базе данных как varchar (12), но на данный момент я не уверен в большей частичто угодно, и любая помощь будет наиболее ценной.

Ответы [ 2 ]

0 голосов
/ 01 октября 2018

Проблема заключается в следующем:

group by rollup(coalesced_value)

Вы группируете по значению после применения coalesce().Следовательно, rollup затем генерирует значение null.

Вместо этого группируйте по столбцу, который находится в данных:

select coalesce(column_1, 'Total') as coalesced_value,     
       sum(column_2) as column_sum
from table 
where yada yada
group by rollup(column_1)
order by (column_1 is null)::int, -- put the total at the end
         coalesced_value;

Это явно упорядочивает результаты в порядкечто ты хочешь их.Результаты будут такими, какими ты хочешь без этого (я думаю).Первая часть (column1 is null)::int является логическим выражением, преобразованным в число.Пустые значения имеют значение true и им присваивается значение 1;ненулевым значениям присваивается значение 0. Это в первую очередь, потому что сортировка по возрастанию (по умолчанию).

0 голосов
/ 01 октября 2018

Я не эксперт в POSTGRESQL, но все же могу дать некоторое представление.Самый простой способ - просто использовать подзапрос:

select coalesce(column_1,'Total') as coalesced_value
,column_sum
from
(
select column_1
,sum(column_2) as column_sum
from table
where yada yada
group by rollup(column_1)
) a
order by coalesced_value;

Если вы хотите избежать подзапроса, вы должны использовать функцию GROUPING.Я знаю, что это работает в Teradata SQL, но после некоторого поиска в Google, похоже, должно работать и в POSTGRESQL:

select case when grouping(column_1) = 1 then 'Total'
else column_1 end as grouping_value
,sum(column_2) as column_sum
from table
where yada yada
group by rollup(column_1)
order by grouping_value;
...