Объединение таблиц на основе даты и времени, но значение даты и времени может изменяться в течение 5 минут - PullRequest
3 голосов
/ 12 декабря 2011

Я работаю с некоторыми довольно плохо спроектированными таблицами, и изменение структуры более или менее исключено.Итак, с учетом сказанного, вот мой вопрос.

Мне нужно присоединиться к TableB.Date на TableA.Date с запасом около 5 минут.Другими словами, объединение не может полагаться на идеальное совпадение.

Таким образом, если дата в Таблице A равна 2011-12-01 10:00:00.000, объединение будет соответствовать записи в Таблице B, в которой указана дата, 2011-12-01 10:03:00.000 или 2011-12-01 09:59:00.000 или 2011-12-01 10:04:35.000

.с небольшой хитростью, чтобы обеспечить разницу разницы около 1 минуты, приведя datetime в smalldatetime, который сбрасывает секунды и миллисекунды со значения datetime.Это работает довольно хорошо, но мне нужен больший запас, чем этот.

LEFT JOIN TableB ON CAST(TableA.SomeDate AS smalldatetime) = CAST(TableB.SomeDate AS smalldatetime)

Столбец даты в TableB является единственной связью между данными в двух таблицах, поэтому я не могу отфильтровать результаты в предложении WHERE.Я понимаю, что это может привести к некоторым неточным результатам, но из-за того, как и когда данные хранятся, я не должен сталкиваться с какими-либо проблемами.

Есть предложения?

Ответы [ 3 ]

5 голосов
/ 12 декабря 2011

Попробуйте DATEDIFF , чтобы искать менее 300 секунд (минутная граница равна нулю, что даст неверные результаты). Для большей точности, используйте миллисекунды <300000 </p>

TableA
LEFT JOIN 
TableB ON ABS(DATEDIFF(second, TableA.SomeDate, TableB.SomeDate)) < 300
1 голос
/ 02 мая 2013

Проблема заключается в том, что для правильной работы SQL необходимо определить 5-минутный запас более жестко. Если вы хотите быть нечетким, тогда SQL - не тот язык.

Что если 2 результата в таблице А находятся в пределах 5 минут друг от друга? Они оба присоединяются к одной и той же записи в таблице B? Затем вы получаете дублированные записи.

То, что вы хотите сделать, это bin ваши даты в 5-минутных сегментах (или что вы выберете), используя план округления вниз / вверх. Предварительно созданная таблица поиска всегда является быстродействующим решением, которая будет содержать столбец индекса каждой минуты каждого дня и другой столбец с согласованными 5-минутными сегментами. Эта промежуточная таблица может использоваться для соединения таблицы A с таблицей B.

т.е. LookupTable (простите за форматирование!)

LookupTime _ __ _ __ _ __ _ BucketTime

2013-01-01 14:56 _ ____ 2013-01-01 14: 55

2013-01-01 14: 57_ _ ___ 2013-01-01 14: 55

2013-01-01 14: 58_ _ ___ 2013-01-01 15: 00

2013-01-01 14: 59_ _ ___ 2013-01-01 15: 00

Вы бы присоединили таблицу Date к описанному выше LookupTime. Вы бы сделали отдельное соединение со второй копией таблицы LookupTime для tableB, Затем соедините две копии таблицы поиска друг с другом в поле BucketTime.

Сложная часть заключается в согласовании округления, которое вы будете использовать. Я рекомендую "Round To Even", который сглаживает смещение округления вверх, которое идет с цифрами округления 1-4 вниз и 5-9 вверх.

0 голосов
/ 12 декабря 2011

Регистрация отформатированных дат.Отформатируйте их так, чтобы они округлялись до ближайших 5 минут или округлялись до соответствующего промежутка времени.Вероятно, потребуется пользовательская функция.

...