ORDER BY Псевдоним не работает

ОБНОВЛЕНИЕ ВОПРОС:

ERROR:  column "Fruits" does not exist

Запуск Postgres 7.4 (Да, мы обновляем)

Почему я не могу использовать ORDER BY для псевдонима столбца? тоже хочет tof."TypeOfFruits" в ORDER BY, почему?

SELECT (CASE
    WHEN tof."TypeOfFruits" = 'A' THEN 'Apple' 
    WHEN tof."TypeOfFruits" = 'P' THEN 'Pear' 
    WHEN tof."TypeOfFruits" = 'G' THEN 'Grapes' 
    ELSE 'Other' END) AS "Fruits",
    SUM(CASE WHEN r.order_date 
        BETWEEN DATE_TRUNC('DAY', LOCALTIMESTAMP) AND DATE_TRUNC('DAY', LOCALTIMESTAMP) + INTERVAL '1 DAY' 
        THEN 1 ELSE 0 END) AS daily, 
    SUM(CASE WHEN r.order_date 
        BETWEEN DATE_TRUNC('MONTH', LOCALTIMESTAMP) AND DATE_TRUNC('MONTH', LOCALTIMESTAMP) + INTERVAL '1 MONTH' 
        THEN 1 ELSE 0 END) AS monthly, 
    SUM(CASE WHEN r.order_date 
        BETWEEN DATE_TRUNC('YEAR', LOCALTIMESTAMP) AND DATE_TRUNC('YEAR', LOCALTIMESTAMP) + INTERVAL '1 YEAR' 
        THEN 1 ELSE 0 END) AS yearly, 
    SUM(CASE WHEN r.order_date >= '01-01-2011 00:00:00' THEN 1 ELSE 0 END) AS lifetime 
FROM reports AS r, "TypeOfFruits" AS tof 
WHERE r.id = tof."ID" 
GROUP BY "Fruits"
ORDER BY CASE 
    WHEN "Fruits" = 'Apple' THEN 1 
    WHEN "Fruits" = 'Pear' THEN 2 
    WHEN "Fruits" = 'Grapes' THEN 3 
    ELSE 4 
END

Результаты на данный момент

Fruits;daily;monthly;yearly;lifetime
"Apple";17;1174;3136;3136
"Pear";28;94;94;94
"Grapes";0;191;490;490
"Other";0;2;27;27
"Other";0;0;1;1
"Other";0;0;27;27
"Other";0;6;28;28
"Other";0;58;229;229
"Other";0;3;3;3
"Other";0;0;1;1

Желаемым результатом будет одна строка с итоговым значением «Другое», то есть всего четыре строки (x будет общим числом).

Fruits;daily;monthly;yearly;lifetime
"Apple";17;1174;3136;3136
"Pear";28;94;94;94
"Grapes";0;191;490;490
"Other";x;x;x;x

person Phill Pafford    schedule 23.06.2011    source источник
comment
Почему Fruit 10 раз пишется с ошибкой как Friut?   -  person crowne    schedule 23.06.2011
comment
хорошо, я исправил проблему с орфографией (черт возьми, вы копируете и вставляете) и немного обновил вопрос   -  person Phill Pafford    schedule 23.06.2011
comment
Хорошая работа, мне нравится ответ @Joe ниже.   -  person crowne    schedule 23.06.2011


Ответы (6)


Вы можете использовать ORDER BY 1 для заказа по первому полю, которое называется «Фрукты». То же самое относится и к GROUP BY

Обновить

Для заказа вместо того, чтобы делать case в order by, создайте новый столбец, скажем, во второй позиции:

(CASE 
    WHEN "Fruits" = 'Apple' THEN 1 
    WHEN "Fruits" = 'Pear' THEN 2 
    WHEN "Fruits" = 'Grapes' THEN 3 
    ELSE 4 ) as Order

Тогда в тебе ORDER BY 2.

person Adriano Carneiro    schedule 23.06.2011
comment
Это помогло с GROUP BY, и я использую @Joe Phillips ORDER BY, но ORDER BY теперь в алфавитном порядке, а не в том порядке, в котором я хотел, отсюда и числовые значения в моем примере. +1 - person Phill Pafford; 23.06.2011
comment
пробуя это, но теперь он хочет GROUP BY tof.TypeOfFruits - person Phill Pafford; 23.06.2011

Причину этого можно найти в документации:

Каждое выражение [в списке ORDER BY] может быть именем или порядковым номером столбца output (элемент списка SELECT) или произвольным выражением, сформированным из input -значения столбцов.

(мой акцент)

Причина этого в том, что старые версии стандарта SQL (SQL-92) допускали сортировку только по имени или номеру выходного столбца, тогда как более новые версии позволяют сортировать по произвольным выражениям, но эти выражения формируются из значений входного столбца.

Другие ответы уже содержат различные подходящие обходные пути для вашего случая.

person Peter Eisentraut    schedule 25.06.2011

Псевдоним назначается после порядка, поэтому вы не можете использовать его в порядке. Используйте это вместо этого:

(CASE
    WHEN tof."TypeOfFruits" = 'A' THEN 'Apple' 
    WHEN tof."TypeOfFruits" = 'P' THEN 'Pear' 
    WHEN tof."TypeOfFruits" = 'G' THEN 'Grapes' 
    ELSE 'Other' END)
person Joe Phillips    schedule 23.06.2011
comment
если я удалю псевдоним AS Fruits, ГРУППА будет отключена, поэтому у меня все еще есть несколько строк других. Или я что-то упускаю? - person Phill Pafford; 23.06.2011
comment
Почему вы его удаляете? Вы можете сохранить его, но вы не можете ссылаться на него в предложении group by или order by - person Joe Phillips; 23.06.2011
comment
Я использую это в ответе ORDER BY w/ @Adrian GROUP BY 1, но теперь ORDER BY не в том порядке, в котором я хотел. Это по алфавиту, есть мысли? +1 - person Phill Pafford; 23.06.2011

Рассмотрим что-то вроде этого:

SELECT * FROM (SELECT (CASE
    WHEN tof."TypeOfFruits" = 'A' THEN 'Apple' 
    WHEN tof."TypeOfFruits" = 'P' THEN 'Pear' 
    WHEN tof."TypeOfFruits" = 'G' THEN 'Grapes' 
    ELSE 'Other' END) AS "Fruits", 
    (CASE 
    WHEN tof."TypeOfFruits" = 'A' THEN 1 
    WHEN tof."TypeOfFruits" = 'P' THEN 2 
    WHEN tof."TypeOfFruits" = 'G' THEN 3 
    ELSE 4 END) as NUM

        FROM ..... <rest of your query without group by and order by .....
    )

GROUP BY Fruits
ORDER BY NUM
person Alex Gitelman    schedule 23.06.2011
comment
Мне нравится эта идея, но она по-прежнему требует tof.TypeOfFruits в GROUP BY. ОШИБКА: подзапрос в FROM должен иметь псевдоним - person Phill Pafford; 23.06.2011
comment
Не уверен, почему. Для внешнего запроса нужны только Fruits и NUM. Можете ли вы уточнить? - person Alex Gitelman; 23.06.2011

Вы можете попробовать что-то вроде этого... не проверено, но я видел подобные запросы.
Дайте мне знать, если это сработает...

SELECT "Fruits",
    SUM(CASE WHEN r.order_date 
        BETWEEN DATE_TRUNC('DAY', LOCALTIMESTAMP) AND DATE_TRUNC('DAY', LOCALTIMESTAMP) + INTERVAL '1 DAY' 
        THEN 1 ELSE 0 END) AS daily, 
    SUM(CASE WHEN r.order_date 
        BETWEEN DATE_TRUNC('MONTH', LOCALTIMESTAMP) AND DATE_TRUNC('MONTH', LOCALTIMESTAMP) + INTERVAL '1 MONTH' 
        THEN 1 ELSE 0 END) AS monthly, 
    SUM(CASE WHEN r.order_date 
        BETWEEN DATE_TRUNC('YEAR', LOCALTIMESTAMP) AND DATE_TRUNC('YEAR', LOCALTIMESTAMP) + INTERVAL '1 YEAR' 
        THEN 1 ELSE 0 END) AS yearly, 
    SUM(CASE WHEN r.order_date >= '01-01-2011 00:00:00' THEN 1 ELSE 0 END) AS lifetime 
FROM reports AS r
    ,(SELECT "ID",
             CASE
                WHEN tof."TypeOfFruits" = 'A' THEN 'Apple' 
                WHEN tof."TypeOfFruits" = 'P' THEN 'Pear' 
                WHEN tof."TypeOfFruits" = 'G' THEN 'Grapes' 
                ELSE 'Other'
             END AS "Fruits" FROM "TypeOfFruits" ) AS "tof"
WHERE r.id = tof."ID" 
GROUP BY "Fruits"
ORDER BY CASE 
    WHEN "Fruits" = 'Apple' THEN 1 
    WHEN "Fruits" = 'Pear' THEN 2 
    WHEN "Fruits" = 'Grapes' THEN 3 
    ELSE 4 
END
person crowne    schedule 23.06.2011

Попробуйте использовать обратные кавычки (`) вместо одинарных/двойных кавычек, чтобы обернуть псевдоним.

Была такая же проблема с MySQL; обратные галочки исправили проблему.

person xsqo    schedule 17.09.2014
comment
MySQL использует обратные кавычки, PostgreSQL использует двойные кавычки, как в стандарте SQL. MySQL не соответствует стандарту. - person felixfbecker; 12.05.2016