SQL - RANK () с несколькими WHERE и GROUP BY - PullRequest
1 голос
/ 08 июля 2020

У меня есть таблица с идентификатором пользователя и датой доступа. (Несколько дат для каждого идентификатора пользователя, но не одинаковое количество дат для каждого.)

Данные выглядят так:

userid | date_accessed
A.     | 2019-01-01
B.     | 2019-01-02
A.     | 2019-01-03
A.     | 2019-01-04
B.     | 2019-01-04

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

userid | date_accessed | rank
A.     | 2019-01-01   | 1
A.     | 2019-01-03    | 2
A.     | 2019-01-04   | 3
B.     | 2019-01-02   | 1
B.     | 2019-01-04   | 2

Мой запрос:

WITH a AS (
  SELECT
    userid
  FROM table_1
  WHERE 
    date_accessed <= '2019-01-01'
    AND date_accessed >= '2019-01-10'
  HAVING
    COUNT(DISTINCT date_accessed) > 1
)

SELECT
    userid,
    date_accessed,
    RANK() OVER (
      PARTITION BY userid
      ORDER BY date_accessed ASC)
FROM table_1
WHERE
    userid IN (SELECT * FROM a)
    AND date_accessed <= '2019-01-01'
    AND date_accessed >= '2019-01-10'
GROUP BY userid, date_accessed

Диапазон дат (date_1 и date_2) охватывает 10-дневный период. Вместо этого происходит то, что мой запрос просто перечисляет / ранжирует все 10 дней для каждого отдельного идентификатора пользователя, хотя не все идентификаторы пользователя должны иметь соответствующие записи для каждой из этих дат. т.е. это выглядит так:

userid | date_accessed | rank
A.     | 2019-01-01   | 1
A.     | 2019-01-02   | 2
A.     | 2019-01-03   | 3
A.     | 2019-01-04   | 4
A.     | 2019-01-05   | 5
...
A.     | 2019-01-10   | 10
B.     | 2019-01-01   | 1
B.     | 2019-01-02   | 2

и т. д.

Я думал, что, возможно, проблема связана с моими GROUP BY, но запрос не запускается без GROUP BY - я нужно как-то вложить мой RANK ()?

Что я делаю не так?

Ответы [ 2 ]

1 голос
/ 09 июля 2020

Вы пробовали ROW_NUMBER вместо RANK? Какова цель GROUP BY?

попробуйте следующее:

;WITH a as
(SELECT 
   userid,
   date_accessed,
   ROW_NUMBER() OVER ( PARTITION BY userid ORDER BY date_accessed ASC) AS rnk
FROM table
WHERE 
   userid IN ( SELECT * FROM other_table )
   AND date_accessed <= 'date_1'
   AND date_accessed >= 'date_2'
)
SELECT userid, date_accessed, rnk
from a
GROUP BY userid, date_accessed
0 голосов
/ 09 июля 2020

Используйте CTE, который будет возвращать отдельные строки для каждого user_id и date_accessed, отфильтрованные по нужным вам датам, а затем используйте ROW_NUMBER() для получения ранга:

WITH cte AS (
  SELECT DISTINCT userid, date_accessed
  FROM table_1
  WHERE date_accessed >= '2019-01-01' AND date_accessed <= '2019-01-10'
)
SELECT userid, date_accessed,
    ROW_NUMBER() OVER (PARTITION BY userid ORDER BY date_accessed ASC) `rank`
FROM cte

См. упрощенный демонстрационный .

...