Как сравнить даты в полях строк для каждого сотрудника отдельно? SQL [дубликат]
Есть таблица: Надо получить из нее вот такую выборку по заданию: Найти модель первой машины каждого из сотрудников и выести в этих полях null, если у сотрудника никогда не было машины 
Отслеживать
4,925 6 6 золотых знаков 11 11 серебряных знаков 29 29 бронзовых знаков
задан 20 июл 2022 в 22:01
21 1 1 бронзовый знак
В чем конкретная сложность? Если бы задача была «Найти модель самой дешевой машины каждого из сотрудников и вывести в этих полях null, если у сотрудника никогда не было машины» — то знаете, как делать? Именно с датой проблема?
20 июл 2022 в 22:24
непонятно, как даты сравнивать не в строке по столбцам, а по строках с условием одно имя
20 июл 2022 в 22:36
Дубликат вопроса Фильтр повторяющихся значений по условию SQL
21 июл 2022 в 4:33
Oracle <> SQL Server <> MySQL <> DB2 <> Cosmos DB, и т.п.
21 июл 2022 в 20:02
MySQL v.8.0 поддерживает CTE: dev.mysql.com/doc/refman/8.0/en/with.html Разные СУБД поддерживают разные диалекты SQL. Вот почему когда задаете вопрос, необходимо предоставить «Минимальный воспроизводимый пример» ##1-4.
21 июл 2022 в 21:10
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
Пожалуйста, попробуйте следующее решение. Это для 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 | +-------+-------------+
Сравнение дат
но выдает ошибку. как сравнивать дату? и еще сразу вопрос как к переменной @date1 прибавить один день?
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Сравнение дат
Подскажите, пожалуйста, как можно сравнивать даты. У меня в таблице с пациентами есть колонка Дата.
Сравнение дат в MSSQL7.0
Есть таблица в MSSQL, а в ней поле dt типа datettime. Выбираю данные например так: или так.
Сравнение двух дат и вывод дат находящихся между ними
Здравствуйте! Тут такое дело, вводятся две определенные ДАТЫ в Edit1 и Edit2 в формате.

Сравнение дат
Добрый день. Подскажите, пожалуйста код Есть уловие: в первом поле таблицы могут находится.
Как сравнивать даты sql
Обычно дата в MSSQL хранится вместе со временем, например 2012-09-02 02:07:38.430 в поле типа DateTime.
Начиная с версии 2008 есть специальные типы данных Date и Time для хранения только даты и только времени соотвественно. Но если программа должна быть совместима со старыми версиями MSSQL, то используется по прежнему стандартный DateTime тип.
Предположим нам необходимо выбрать все записи за один день, например сегодня 2012-09-02.
Как показывает практика, простое сравнение даты и строки «2012-09-02» работает в 2005 и 2008 серверах (вероятно и 2000 тоже). Например:
SELECT * FROM SpecialDay WHERE [Date]=’2012-09-02′
Однако версия MSSQL 2012 уже не вернет никаких записей по такому запросу. И даже точное указание времени, при том что в базе лежат записи с нулевым временем,
SELECT * FROM SpecialDay WHERE [Date]=’2012-09-02 00:00:00.000′ тоже не работает.
Кроме того, дата может быть как в формате YYYY.DD.MM, так и в YYYY.MM.DD, точность милисекунд может быть разной, и разделитель частей год, месяц и день может быть разным.
Поэтому я научился делать так:
DECLARE @date DATETIME;
SET @date = CONVERT(DATETIME, ‘2012-09-02’, 120);
SELECT * FROM SpecialDay WHERE
[Date] >= @date
AND [Date] < DATEADD(d, 1, @date)
Это точно работает во всех версиях MSSQL начиная с 2000.
Тут CONVERT(DATETIME, ‘2012-09-02’, 120) переводит строку в тип даты 120 — канонический формат ODBC гггг-мм-дд чч:ми:сс (24-часовой формат) . Конвертирует с любым разделителем: и сточкой и со слешем и с тире.
Список форматов даты в MSSQL
0 или 100 ( 1, 2 )
Как сравнивать даты sql
Строковый формат даты сравнивать недопустимо:
IF (‘15.05.2002’ > ‘31.03.2002’)
PRINT ‘Больше’
ELSE
PRINT ‘Меньше’
Выдает значение: ‘Меньше’
Сравнивать даты можно только в формате даты:
IF (CONVERT(DATETIME, CONVERT(varchar,GetDate(),104)) > CONVERT(DATETIME, ‘31.03.2002’))
PRINT ‘Больше’
ELSE
PRINT ‘Меньше’
Server: Msg 242, Level 16, State 3, Line 1
The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value.
Меньше
Best wishes, Taras
Re: Как сравнивать даты в MS SQL
| От: | Toughpheeckouse | |
| Дата: | 15.05.02 06:00 | |
| Оценка: | 2 (1) | |
Здравствуйте Good Man, Вы писали:
GM>Строковый формат даты сравнивать недопустимо:
GM>IF (‘15.05.2002’ > ‘31.03.2002’)
GM>PRINT ‘Больше’
GM>ELSE
GM>PRINT ‘Меньше’
GM>Выдает значение: ‘Меньше’
если он правильно записан, то допустимо
IF ( > ) PRINT 'Больше' ELSE PRINT 'Меньше'
ODBC defines escape sequences for date, time, and timestamp literals. The syntax of these escape sequences is as follows: In BNF notation, the syntax is as follows: ODBC-date-time-escape ::= ODBC-date-escape | ODBC-time-escape | ODBC-timestamp-escape ODBC-date-escape ::= ODBC-esc-initiator d 'date-value' ODBC-esc-terminator ODBC-time-escape ::= ODBC-esc-initiator t 'time-value' ODBC-esc-terminator ODBC-timestamp-escape ::= ODBC-esc-initiator ts 'timestamp-value' ODBC-esc-terminator ODBC-esc-initiator ::= < ODBC-esc-terminator ::= >date-value ::= years-value date-separator months-value date-separator days-value time-value ::= hours-value time-separator minutes-value time-separator seconds-value timestamp-value ::= date-value timestamp-separator time-value date-separator ::= - time-separator ::= : timestamp-separator ::= (The blank character) years-value ::= digit digit digit digit months-value ::= digit digit days-value ::= digit digit hours-value ::= digit digit minutes-value ::= digit digit seconds-value ::= digit digit[.digit…]
Думайте сами, решайте сами.
Re: Как сравнивать даты в MS SQL
| От: | vav | |
| Дата: | 15.05.02 08:44 | |
| Оценка: | 1 (1) | |
GM>Server: Msg 242, Level 16, State 3, Line 1
GM>The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value.
А как должен сервер понимать твою строку?
как ‘dd.mm.yyyy’, ‘mm.dd.yyyy’ или еще как-нибудь?
Если строка получается на клиенте, то рекомендую передавать параметры как datatime, а не как строку..
Если нужно иметь эту переменную на сервере, то
составь свою дату из кусочков используя DATEADD
(хотя можно конечно изменить строку на ‘03.31.2002’ и все заработает до первого изменения региональных настроек)
Re[2]: Как сравнивать даты в MS SQL
| От: | Good Man |
| Дата: | 15.05.02 15:43 |
| Оценка: |
Где “ Date_update” типа DateTime.
Best wishes, Taras
Re: Как сравнивать даты в MS SQL
| От: | Sinclair | https://github.com/evilguest/ |
| Дата: | 15.05.02 20:59 | |
| Оценка: | 1 (1) | |
Здравствуйте Good Man, Вы писали:
GM>Строковый формат даты сравнивать недопустимо:
GM>IF (‘15.05.2002’ > ‘31.03.2002’)
GM>PRINT ‘Больше’
GM>ELSE
GM>PRINT ‘Меньше’
GM>Выдает значение: ‘Меньше’
вообще-то надо так:
IF GetDate() > CONVERT(DATETIME, '31.03.2002', 104)) PRINT 'Больше' ELSE PRINT 'Меньше'
GM>Возникает ошибка:
GM>Server: Msg 242, Level 16, State 3, Line 1
GM>The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value.
Логично, черт возьми. Он не может понять, как конвертить ‘31.03.2002’ в дату — надо указать стиль.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Как сравнивать даты в MS SQL
| От: | Good Man |
| Дата: | 16.05.02 02:44 |
| Оценка: |
Здравствуйте Sinclair, Вы писали:
Какая выборка будет, производится быстрее в MS SQL 2000?
Предположим, что есть таблица «Table1». В таблице есть поле “DateField1” типа DateTime. Приведу два примера:
SELECT * FROM Table1
WHERE CONVERT(varchar, DateField1, 104) = ‘15.05.2002’
SELECT * FROM Table1
WHERE DateField1 = CONVERT(DATETIME, ‘2002-05-15 00:00:00’, 102)»;
В Access вообще нет необходимости заниматься конвертированием:
«…WHERE DateField1 = #05/15/02#…»
Конвертирование, при сравнении дат, должно сильно уменьшать скорость выборки данных в MS SQL 2000.
Best wishes, Taras
Re[3]: Как сравнивать даты в MS SQL
| От: | Sinclair | https://github.com/evilguest/ |
| Дата: | 16.05.02 07:30 | |
| Оценка: | 2 (1) | |
Здравствуйте Good Man, Вы писали:
GM>Здравствуйте Sinclair, Вы писали:
GM>Какая выборка будет, производится быстрее в MS SQL 2000?
GM>Предположим, что есть таблица «Table1». В таблице есть поле “DateField1” типа DateTime. Приведу два примера:
GM>Вариант 1:
GM>SELECT * FROM Table1
GM>WHERE CONVERT(varchar, DateField1, 104) = ‘15.05.2002’
GM>Вариант 2:
GM>SELECT * FROM Table1
GM>WHERE DateField1 = CONVERT(DATETIME, ‘2002-05-15 00:00:00’, 102)»;
Ясен пень — вариант 2 будет выполняться не медленнее, т.к. в нем преобразование выполняется лишь раз — в начале запроса. Использование непреобразованного значения поля позволяет оптимизировать запрос при помощи индексов. Суперумный сервер мог бы построить обратное преобразование в случае 1 и свести его к случаю 2. Например, запрос
select * from t2 where int_field*2+1 < 41
легко сводится к
select * from t2 where int_field < 20
Но я сииильно сомневаюсь, что преобразование даты в строку может быть так соптимизировано хотя бы одним из существующих серверов. Даже запросы типа
select * from t2 where int_field1+int_field2
и то выполняются фулл сканом.
GM>В Access вообще нет необходимости заниматься конвертированием:
GM>«…WHERE DateField1 = #05/15/02#…»
GM>Конвертирование, при сравнении дат, должно сильно уменьшать скорость выборки данных в MS SQL 2000.
Нет. Правильно эта фраза читается вот так:
Конвертирование при сравнении дат может сильно уменьшить скорость выполнения запроса в MS SQL 2000
Вариант 2, рассмотренный выше, выполняется не хуже, чем select * from t2 where int_field < 20.
