У меня есть таблица Hive с полем даты в формате String, как показано ниже

"2013-05-01 00:10:41.0"

Я получил противоречивые результаты между следующими запросами:

SELECT COUNT(*)
FROM table
WHERE mdate >= '2013-05-01' AND mdate <= '2013-05-31';

--> gives 111930


SELECT COUNT(*)
FROM table
WHERE mdate regexp '^2013-05-\\d{2}.*';

--> gives 115038

Есть какие-нибудь подсказки, почему это происходит?

0
revy 20 Сен 2018 в 13:24

2 ответа

Лучший ответ

Я согласен с предложением @Gordon, однако он не отвечает на вопрос, и в этом случае неявное преобразование отсутствует, вы сравниваете 2 строки. В первом сравнении вы получаете меньше значений, потому что вы выдаете все значения -31. Вы можете запустить это, чтобы проверить ..

select "2013-05-31 00:00:00.0" <= '2013-05-31' ; - ложь

select "2013-05-30 00:00:00.0" <= '2013-05-31' ; - верно

Это потому, что вы выполняете лексикографическое сравнение ... и на самом деле '2013-05-31' меньше, чем "2013-05-31 00:00:00.0"

Если бы я предположил о менее дорогостоящем способе выполнения этого сравнения, я бы сказал, что это substr и compare (регулярные выражения обычно дороги, и приведение к дате также может быть).

select substr("2013-05-31 00:00:00.0",1,10) <= '2013-05-31' ;
1
hlagos 20 Сен 2018 в 11:32

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

Обычно, если вам нужны все даты в мае, вы должны использовать:

SELECT COUNT(*)
FROM table
WHERE mdate >= '2013-05-01' AND mdate < '2013-06-01';

Это работает, даже если mdate имеет компонент времени.

0
Gordon Linoff 20 Сен 2018 в 10:26