Нахождение нет. новых или находящихся в поездке экземпляров - PullRequest
0 голосов
/ 02 октября 2019

В очень большой таблице sql даются миллионы дат. Как я могу узнать в любой момент, сколько поездок идет и сколько поездок началось? Редактировать: Столбцы в таблице: -

  1. Дата и время начала поездки
  2. Дата и время окончания поездки
  3. Нет. Путешественников
  4. Общий доход (налоги, тарифы и т. Д. Все включено)
  5. Расстояние поездки

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

Надеюсь, этой информации достаточно.

1 Ответ

0 голосов
/ 02 октября 2019

Первый для таблицы календаря в памяти, гранулированный ко второму. Этот запрос возвращает каждый час / минуту / секунду между @startdate и @ enddate

DECLARE 
  @startdate DATETIME = '2019-01-01 06:00:00.000',
  @enddate   DATETIME = '2019-01-01 07:00:00.000';

WITH 
E1 AS (SELECT N = 1 FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) AS x(x)),
E3 AS (SELECT N = 1 FROM E1 a, E1 b, E1 c),
iTally(N) AS
(
  SELECT TOP(DATEDIFF(SECOND,@startdate,@enddate)+1) 
    ROW_NUMBER() OVER (ORDER BY (SELECT 1))-1
  FROM E3 a, E3 b
),
Calendar AS
(
  SELECT DT = DATEADD(SECOND,i.N,@startdate)
  FROM       iTally AS i
)
SELECT c.DT FROM Calendar AS c

Возвращает:

DT
-----------------------
2019-01-01 06:00:00.000
2019-01-01 06:00:01.000
2019-01-01 06:00:02.000
2019-01-01 06:00:03.000
...
2019-01-01 06:59:56.000
2019-01-01 06:59:57.000
2019-01-01 06:59:58.000
2019-01-01 06:59:59.000
2019-01-01 07:00:00.000

Мы можем использовать эту таблицу для соединения влевок вашей таблице с информацией о "поездках"

-- Date Boundary Parameters
DECLARE 
  @startdate DATETIME = '2019-01-01 06:00:00.000',
  @enddate   DATETIME = '2019-01-01 07:00:00.000';

-- Easily consumable sample data
DECLARE @ride TABLE 
(
  rideId     INT identity,
  RideStart  DATETIME NOT NULL,
  RideEnd    DATETIME NOT NULL
);

INSERT @ride (RideStart,RideEnd) VALUES 
('2019-01-01 06:00:01.000', '2019-01-01 06:33:12.000'),
('2019-01-01 06:00:04.000', '2019-01-01 06:14:19.000'),
('2019-01-01 06:02:15.000', '2019-01-01 06:05:48.000'),
('2019-01-01 06:02:47.000', '2019-01-01 06:04:21.000');

-- Solution
WITH 
E1 AS (SELECT N = 1 FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) AS x(x)),
E3 AS (SELECT N = 1 FROM E1 a, E1 b, E1 c),
iTally(N) AS
(
  SELECT TOP(DATEDIFF(SECOND,@startdate,@enddate)+1) 
    ROW_NUMBER() OVER (ORDER BY (SELECT 1))-1
  FROM E3 a, E3 b
),
Calendar AS
(
  SELECT DT = DATEADD(SECOND,i.N,@startdate)
  FROM       iTally AS i
)
SELECT TOP (2000)
  DT         = c.DT,
  InProgress = COUNT(r.rideId)
FROM      Calendar AS c
LEFT JOIN @ride    AS r ON c.DT BETWEEN r.RideStart AND r.RideEnd
GROUP BY  c.DT;

Это возвращает:

DT                        InProgress
------------------------- -----------
2019-01-01 06:00:00.000   0
2019-01-01 06:00:01.000   1
2019-01-01 06:00:02.000   1
2019-01-01 06:00:03.000   1
2019-01-01 06:00:04.000   2
2019-01-01 06:00:05.000   2
...                       
2019-01-01 06:02:15.000   3
2019-01-01 06:02:16.000   3
...                       
2019-01-01 06:02:47.000   4
2019-01-01 06:02:48.000   4
2019-01-01 06:02:49.000   4
...                       
2019-01-01 06:14:17.000   2
2019-01-01 06:14:18.000   2
2019-01-01 06:14:19.000   2
2019-01-01 06:14:20.000   1
2019-01-01 06:14:21.000   1

Добавление логики для "поездок началось" должно быть легко здесь. Я собирался сделать это, но не хватило времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...