Выбор каждой N-й строки для пользователя в Postgres - PullRequest
2 голосов
/ 22 сентября 2011

Я использовал этот оператор SQL:

SELECT "dateId", "userId", "Salary" 
FROM (
   SELECT *, 
          (row_number() OVER (ORDER BY "userId", "dateId"))%2 AS rn 
   FROM user_table
 ) sa 
 WHERE sa.rn=1 
   AND "userId" = 789 
   AND "Salary" > 0;

Но каждый раз, когда таблица получает новые строки, результат запроса будет другим.
Я что-то упустил?

Ответы [ 3 ]

5 голосов
/ 23 сентября 2011

Предполагая, что ("dateId", "userId") уникально и новые строки всегда имеют больший (позже) dateId.

После некоторых комментариев:

Что я думаю тебе нужно:

SELECT "dateId", "userId", "Salary"
FROM (
   SELECT "dateId", "userId", "Salary"
         ,(row_number() OVER (<b>PARTITION BY "userId"</b>   -- either this
                              ORDER BY "dateId")) % 2 AS rn
   FROM   user_table
   <b>WHERE  "userId" = 789</b>                              -- ... or that
   ) sub
WHERE  sub.rn = 1
AND    "Salary" > 0;

Обратите внимание на PARTITION BY. Таким образом, вы пропускаете каждую секунду dateId для каждого userId, и дополнительные (более поздние) строки пока не изменяют выбор.

Кроме того, пока вы выбираете строки для одного userId (WHERE "userId" = 789), перетяните предикат в подзапрос, добившись того же эффекта (стабильный выбор для одного пользователя). Вам не нужны оба.

Предложение WHERE в подзапросе работает только для одного пользователя, PARTITION BY работает для любого количества пользователей в одном запросе.

Это так? Это так?
Они должны дать мне «детективный» значок за это.
Серьезно.

0 голосов
/ 23 сентября 2011

Если кто-то вставит новую строку с ИД пользователя ниже 789, порядок изменится.Например, если у вас есть:

userId rn
 1      1
 4      0
 5      1
 6      0

и вы вставляете строку с userId = 2, rn изменится:столбец с последовательностью или отметкой времени.

0 голосов
/ 23 сентября 2011

Нет, похоже, все в порядке.У вас есть новые строки, эти строки изменяют старые строки, чтобы после сортировки отображаться в другом положении.

...