PostgreSQL - выбрать отдельно - порядок по полю не возвращается в select - PullRequest
2 голосов
/ 29 ноября 2011

В настоящее время мы переносим нашу базу данных из Firebird в PostgreSQL. Мы используем NHibernate в качестве ORM, и переход был довольно безболезненным, хотя в SQL было несколько отличий.

У нас есть один запрос, который мы выполняем, используя NHibernate.CreateSQLQuery, когда сами строим SQL. Запрос возвращает строку List из 5 самых последних использованных имен Ninja для переданных в UserID.

Это не было проблемой в Firebird с использованием следующего SQL;

 SELECT FIRST 5 DISTINCT NI.NINJA_NAME
 FROM NINJA_ACCESS NA 
      INNER JOIN NINJAS NI ON NA.NINJA_ID = NI.NINJA_ID
 WHERE NA.USER_ID = 1
 ORDER BY NI.NINJA_ACCESS_DATE DESC

Возвращение упорядоченного (по убыванию даты доступа) списка строк.

Теперь в PostgreSQL мы сталкиваемся с проблемами с этим простым запросом;

 SELECT DISTINCT ON (NI.NINJA_NAME) NI.NINJA_NAME
 FROM NINJA_ACCESS NA 
      INNER JOIN NINJAS NI ON NA.NINJA_ID = NI.NINJA_ID
 WHERE NA.USER_ID = 1
 ORDER BY NI.NINJA_ACCESS_DATE DESC
 LIMIT 5

Похоже, мы не можем вернуть один «отдельный» столбец данных с упорядочением, выполненным для отдельного столбца, который не включен в выборку. Любое изменение в приведенном выше SQL не будет работать, если мы не включим столбец Access_Date в select.

Есть идеи, как мы можем решить этот простой запрос в PostgreSQL?

Примечание: это важный запрос для нашей системы управления ниндзя, настаивает на том, что она работает !!!

1 Ответ

2 голосов
/ 29 ноября 2011

Этот запрос должен быть эквивалентным:

SELECT n.ninja_name
      ,max(n.ninja_access_date) AS max_access_date
FROM   ninja_access na 
JOIN   ninjas n USING (ninja_id)
WHERE  na.user_id = 1
GROUP  BY n.ninja_name
ORDER  BY 2 DESC
LIMIT  5;
  • ORDER BY 2 - это просто сокращение для ORDER BY max(n.ninja_access_date).
  • Нам нужно max(n.ninja_access_date), чтобы получить максимум недавняя запись для ninja_name.
    И сортировка по убыванию, чтобы получить самые последние имена.
  • JOIN ninjas n USING (ninja_id) - сокращение от
    JOIN ninjas n ON n.ninja_id = na.ninja_id

Вам не нужно включать дату доступа в список SELECT.Чтобы получить только имена:

SELECT n.ninja_name
FROM   ninja_access na 
JOIN   ninjas ni USING (ninja_id)
WHERE  na.user_id = 1
GROUP  BY n.ninja_name
ORDER  BY max(n.ninja_access_date) DESC
LIMIT  5;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...