Самая ранняя запись SQL - PullRequest
       6

Самая ранняя запись SQL

0 голосов
/ 28 января 2019

Допустим, у меня есть таблица заказов с 20 столбцами.Меня интересуют только первые 4 столбца: id, Department_id, region_id, datetime, где id - это идентификатор клиента, а datetime - время, когда клиент разместил заказ.Другие столбцы более специфичны для деталей продукта (например, product_id), поэтому в данном заказе вы можете иметь несколько строк.Я изо всех сил пытаюсь написать запрос, чтобы получить для каждого клиента самый ранний отдел и регион, поскольку один и тот же клиент может иметь несколько комбинаций Department_id и region_id.

SELECT a.*
FROM (
    SELECT id,
        department_id,
        region_id,
        min(DATETIME) AS ts
    FROM orders
    GROUP BY id,
        department_id,
        region_id
    ) a
INNER JOIN (
    SELECT id,
        min(DATETIME) AS ts
    FROM orders
    GROUP BY id
    ) b
    ON a.id = b.id
        AND a.ts = b.ts

Это работает, но это не таккажется очень эффективным и плохо написанным.Есть ли лучший способ написать это?Сама таблица довольно большая, поэтому этот запрос медленный.

Ответы [ 3 ]

0 голосов
/ 28 января 2019

Использовать dense_rank() аналитическую функцию:

SELECT 
        id,
        department_id,
        region_id,
        min(DATETIME) AS ts
 FROM
(
SELECT  id,
        department_id,
        region_id,
        DATETIME,
        dense_rank() over(partition by id order by DATETIME) AS rnk
  FROM orders
)s 
WHERE rnk=1 --records with minimal date by id
GROUP BY id,
         department_id,
         region_id;

Этот запрос выполняет то же самое, что и ваш, но таблица будет сканироваться один раз, без объединения.

0 голосов
/ 28 января 2019

Я бы просто сделал:

SELECT id, department_id, region_id, datetime
FROM (SELECT o.*
             row_number() over (partition by id order by datetime) as seqnum
      FROM orders o
     ) o
where seqnum = 1;

РЕДАКТИРОВАТЬ:

Вы можете попробовать эту версию, чтобы увидеть, работает ли она лучше:

select o.*
from orders o join
     (select id, min(datetime) as min_datetime
      from orders
      group by id
     ) oo
     on oo.id = o.id and oo.datetime = o.datetime;

В большинстве баз данныхверсия row_number(), вероятно, будет иметь лучшую производительность.Однако Hive может принимать загадочные решения по оптимизации, и это может быть лучше.

0 голосов
/ 28 января 2019

Я думаю, что вы, возможно, могли бы использовать, как это:

SELECT id, department_id, region_id, min(datetime) AS ts 
FROM orders 
GROUP BY id, department_id, region_id 
HAVING ts=min(datetime)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...