LINUX.ORG.RU

SQL же

 


1

1

Всем привет!

Есть две таблицы см.внизу, нужно получить одну таблицу, но чтобы допустим значение даты в записи было ближе всего к 16:00. Т.е. берём соответствующие записи из Таблицы 1 и Таблицы 2, у них равны ID и Tariff. Затем сравниваем время у кого ближе оно к 16:00 того и кладём в результирующую таблицу. Например:

Таблица 1
| 6  |   0    |	2019-06-13 15:59:36.000 | <-- Эта должна попасть в итоговый выхлоп
Таблица 2
| 6  |   0    |	2019-06-13 16:01:20.000 | <-- Это игнорируется

ID и Tariff - это int, тогда как DateTime, внезапно, datetime. Таблицы для примеров:

>> Таблица 1 
+----+--------+-------------------------+
| ID | Tariff |         DateTime        |
+----+--------+-------------------------+ 
| 6  |   0    |	2019-06-13 15:59:36.000 |
| 7  |	 0    |	2019-06-13 15:59:37.000 |
| 8  |	 0    |	2019-06-13 15:59:39.000	|
| 12 |	 0    |	2019-06-13 15:59:40.000 |
+----+--------+-------------------------+

>> Таблица 2
+----+--------+-------------------------+
| ID | Tariff |         DateTime        | 
+----+--------+-------------------------+
| 6  |   0    |	2019-06-13 16:01:20.000 |
| 7  |   0    |	2019-06-13 16:01:22.000 |
| 8  |   0    |	2019-06-13 16:01:23.000 |
| 12 |   0    |	2019-06-13 16:01:24.000 |
+----+--------+-------------------------+

Собственно, как сделать?

★★★★

Для одной таблицы можно вот так:

SELECT * FROM
  (
    (SELECT * FROM table1 WHERE num >= date ORDER BY num LIMIT 1)
        UNION ALL
    (SELECT * FROM table1 WHERE num < date  ORDER BY num DESC LIMIT 1)
  ) as r1
ORDER BY abs(?-date) LIMIT 1;
egorcod
()
Ответ на: комментарий от egorcod

Ну ещё надо уточнить, что это майкрософтовское поделие не понимает что такое LIMIT

AntonyRF ★★★★
() автор топика
Ответ на: комментарий от AntonyRF

Упс, ошибочка Вот так вот надо

SELECT * FROM
  (
    (SELECT * FROM table1 WHERE date >= needed ORDER BY num LIMIT 1)
        UNION ALL
    (SELECT * FROM table1 WHERE date < needed ORDER BY num DESC LIMIT 1)
  ) as r1
ORDER BY abs(needed - date) LIMIT 1;

needed - нужная дата

egorcod
()
Ответ на: комментарий от egorcod

Столбец у меня называется DateTime (да да как и тип данных), но не он и не date не подходят, ругается на :

Неявное преобразование из типа данных datetime в float не разрешено. Для выполнения этого запроса используйте функцию CONVERT.

AntonyRF ★★★★
() автор топика
Ответ на: комментарий от egorcod

Короче, ошибка на SELECT * FROM, по отдельности

SELECT * FROM table1 WHERE date >= needed ORDER BY num LIMIT 1

Выполнился

AntonyRF ★★★★
() автор топика

На PostgreSQL будет так:

select id, tariff,
       case
         when abs(
                 extract(epoch from table1.datetime)
               - extract(epoch from '2016-06-13T16:00:00.000'::timestamp)
              ) < abs(
                 extract(epoch from table2.datetime)
               - extract(epoch from '2016-06-13T16:00:00.000'::timestamp)
              )
         then table1.datetime
         else table2.datetime
       end
  from table1 join table2 using (id, tariff);

Jini ★★
()
Ответ на: комментарий от no-such-file

Упоролся что ли? Или с SO скопипастил (тупо)?

Да, его вариант не подходит, выводит только одну запись.

AntonyRF ★★★★
() автор топика
Ответ на: комментарий от AntonyRF

Тебе вообще что конкретно надо-то? Для каждого id/tarif найти одну запись ближайшую к дате? Или найти такой id/tariff (один) который ближе всего к дате?

no-such-file ★★★★★
()
Ответ на: комментарий от AntonyRF
declare @target datetime='20190613 16:00:00.000'
select id, tarif, DateTime 
from 
	(	select id, tarif, DateTime
			, rn=row_number() over (partition by id, tarif order by delta, DateTime)
		from 
			(	select id, tarif, DateTime from #table1
			union
				select id, tarif, DateTime from #table2
			) d
		cross apply 
			(	select delta=abs(datediff(ms,d.Datetime, @target)) 
			) d1
	) t
where t.rn=1
nosuchuser
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.