Как сравнить даты в полях строк для каждого сотрудника отдельно? SQL

Есть таблица:

введите сюда описание изображения

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

введите сюда описание изображения


Ответы (2 шт):

Автор решения: Сергей

Я все-таки доделал вывод (немного поумнев в процессе) - ниже код, как "даты сравнивать не в строке по столбцам, а по строках с условием одно имя". Отдельное спасибо @andreymal за обнаружение ошибки в синтаксисе у меня.

Код - в синтаксисе mySQL. Название вашей таблицы не знаю, тут использовал оригинальное имя table.

SELECT
    name,
    model AS first_brand   
FROM table
WHERE (name, start_date) 
    IN
    (   SELECT
            name, MIN(start_date)
        FROM
            table
        GROUP BY name
 )

Относительно вывода null - должна быть просто модификация строки 3 к IFNULL (model, null) AS first_brand, но не проверить на моей учебной БД (там запрет на внесение записей с NULL).

→ Ссылка
Автор решения: Yitzhak Khabinsky

Пожалуйста, попробуйте следующее решение. Это для MS SQL Server.

CTE создает сегменты для каждого сотрудника, упорядоченные по дате. Вот почему внешний SELECT использует seq=1, то есть модель первой машины.

Невидимый вывод из CTE:

+-----+--------+----------+------------+----+-------+-------------+-----+
| _ID | car_id | owner_id | start_date | id | _Name |    model    | seq |
+-----+--------+----------+------------+----+-------+-------------+-----+
|   1 | 1      | 1        | 2016-04-12 |  1 | John  | Volvo XC90  |   1 |
|   6 | 45     | 1        | 2016-10-17 |  1 | John  | Opel Astra  |   2 |
|   4 | 15     | 2        | 2016-04-12 |  2 | Kim   | Volvo XC90  |   1 |
|   2 | 1      | 2        | 2016-10-17 |  2 | Kim   | Volvo XC90  |   2 |
|   5 | 34     | 3        | 2016-04-12 |  3 | Smith | Opel Zafira |   1 |
|   3 | 1      | 3        | 2016-12-19 |  3 | Smith | Volvo XC90  |   2 |
|   7 | NULL   | NULL     | NULL       |  4 | Paul  | NULL        |   1 |
+-----+--------+----------+------------+----+-------+-------------+-----+

SQL

-- DDL и образец вставки данных, начало
DECLARE @tbl TABLE (
    _ID INT IDENTITY PRIMARY KEY, 
    car_id INT,
    owner_id INT,
    [start_date] DATE,
    id INT,
    _Name  VARCHAR(20),
    model VARCHAR(20)
);
INSERT INTO @tbl (car_id, owner_id, [start_date], id, _Name, model) VALUES
(1, 1, '2016-04-12', 1, 'John', 'Volvo XC90'),
(1, 2, '2016-10-17', 2, 'Kim', 'Volvo XC90'),
(1, 3, '2016-12-19', 3, 'Smith', 'Volvo XC90'),
(15, 2, '2016-04-12', 2, 'Kim', 'Volvo XC90'),
(34, 3, '2016-04-12', 3, 'Smith', 'Opel Zafira'),
(45, 1, '2016-10-17', 1, 'John', 'Opel Astra'),
(NULL, NULL, NULL, 4, 'Paul', NULL);
-- DDL и образец вставки данных, конец

;WITH rs AS
(
    SELECT *
        , seq = ROW_NUMBER() OVER (PARTITION BY id ORDER BY [start_date] ASC)
    FROM @tbl
)
SELECT _Name, model AS first_brand
FROM rs
WHERE seq = 1
ORDER BY id;

Результат

+-------+-------------+
| _Name | first_brand |
+-------+-------------+
| John  | Volvo XC90  |
| Kim   | Volvo XC90  |
| Smith | Opel Zafira |
| Paul  | NULL        |
+-------+-------------+
→ Ссылка