Попытка получить первую запись из группы в SQL

#sql #datetime #apache-spark-sql #greatest-n-per-group #min

#sql #datetime #apache-spark-sql #наибольшее число записей на группу #мин

Вопрос:

Я пытаюсь запросить самую раннюю временную метку для кандидата, для проекта, для контракта на spark SQL.

 spark.sql(
      """
        |SELECT
        | DISTICT
        | timestamp,
        | candidate_id,
        | project_id,
        | contract_id
        |FROM candidatesHistory
        |GROUP BY timestamp, candidate_id, project_id, contract_id
        |ORDER BY timestamp DESC
        |LIMIT 1
        |""".stripMargin)
  

Этот код этого не делает, он просто извлекает одну запись — как мне получить самую старую временную метку для кандидата на проект для контракта?

Любая помощь приветствуется

Ответ №1:

Если в таблице всего 4 столбца, вы можете использовать агрегацию:

 select candidate_id, project_id, contract_id, min(timestamp) first_timestamp
from candidateshistory
group by candidate_id, project_id, contract_id
  

Если столбцов больше, и вы хотите привести их все, то вы можете использовать row_number() для фильтрации таблицы:

 select ch.*
from (
    select ch.*,
        row_number() over(partition by candidate_id, project_id, contract_id order by timestamp) rn
    from candidateshistory ch
) ch
where rn = 1
  

Для каждого (candidate_id, project_id, contract_id) кортежа это дает вам строку с самым ранним timestamp .

Комментарии:

1. Мне не нужна последняя, мне нужна самая ранняя, поэтому я заказываю по DESC.

2. @TannishaHill: это простое исправление для запроса. Выполнено. Обратите внимание, что, в отличие от того, что вы, кажется, думаете, порядок по убыванию ставит последнюю на первое место (что на самом деле вводит меня в заблуждение).

Ответ №2:

Это должно сработать, хотя не знаю, лучший ли это способ:

 SELECT candidate_id
, project_id
, contract_id
, timestamp
FROM (
    SELECT RANK() OVER (PARTITION BY candidate_id ORDER BY timestamp) AS RNK
    , candidate_id
    , project_id
    , contract_id
    FROM candidatesHistory
    ) as CH
WHERE CH.RNK = 1;