Ошибка PostgreSQL, которую я не могу понять - PullRequest
2 голосов
/ 09 декабря 2011

У меня есть SQL-запрос, который должен найти ранг определенного повара.Я должен подсчитать количество рецептов, которые приготовил этот повар, подсчитать количество рецептов других поваров, и конечная цель - получить рейтинг нашего повара, то есть количество поваров, которые сделали меньше рецептов, чем он.(Извините за мой плохой английский и длинное объяснение).

Запрос:

 /*Compute Cooking Rank*/
 create or replace function
 ComputeCookingRank(u integer)
 returns integer as $$
 declare
 uidSum record; 
 uSum integer;
 ranking integer; 
 begin 
 select distinct uid,count(uid) as "sum" into uidSum from HasCooked group by uid;
 ---> select distinct into uSum from uidSum where uid=u;
 select count(uid) into ranking from uidSum where uid=u and sum<uSum;
 end;
 $$ language plpgsql; 

Проблемная строка - та, что со стрелкой;это нормально, чтобы взять данные из переменной типа «запись», как это?Что я тут не так делаю?

Ответы [ 2 ]

2 голосов
/ 09 декабря 2011
select distinct /* you list no columns here */ into uSum from uidSum where uid=u;
1 голос
/ 09 декабря 2011

Прежде всего, вам не нужна функция plpgsql для этого. Простой запрос делает работу. A CTE помогает в этом случае:

WITH x AS (
    SELECT uid, count(*) as ct
    FROM   hascooked
    GROUP  BY uid
    )
SELECT count(*) AS cooks_with_fewer_recipies
FROM   x
WHERE  ct < (SELECT ct FROM x WHERE uid = u);

Далее, количество вещей неправильно с этим утверждением:

select distinct uid,count(uid) as "sum" into uidSum from HasCooked group by uid;

Эти пункты - только мой совет, не совсем неправильный:

  • Вы уже GROUP BY uid, а DISTINCT бессмысленно в данном конкретном случае.

  • Не используйте имя функции (sum) в качестве имени столбца. Только приводит к проблемам.

  • При правильном имени вам не нужны двойные кавычки ("sum"). Только мой совет, не совсем неверный.

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

  • Поскольку вы GROUP BY uid, лучше использовать count(*) вместо count(uid). Немного быстрее и лучшие результаты в (маловероятном?) Случае, когда uid может быть NULL - тогда вы получите счет и для NULL - случаев.

Очищенная форма ( все еще не так! ):

SELECT uid, count(*) as ct INTO uidSum
FROM   hascooked
GROUP  BY uid;

Оператор по-прежнему неверен, поскольку вы пытаетесь присвоить несколько строк одной переменной uidSum, что невозможно.

A record может содержать несколько столбцов , а не несколько строк . Для этого вам нужно table или объединить строки в одну.

Будет назначена только первая строка, которая выбрана в random , поскольку у вас нет ORDER BY. DISTINCT используется для гарантии того, что результирующий набор упорядочен по столбцам DISTINCT, но это не так с версии 8.4. Я цитирую заметки о выпуске для 8.4

SELECT DISTINCT и UNION / INTERSECT / EXCEPT больше не всегда производят отсортированный вывод (Том)

В любом случае упорядочение по uid столь же бессмысленно, как и получение одной строки в этом контексте. Это явно не то, что вы хотите. Другим способом было бы перебрать получившиеся строки, одну за другой. Подробнее о циклах здесь .

Правильным решением является мой запрос выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...