2017-02-23 82 views
0
SELECT 
count(added_to_cart=1) AS all_addtocart, 
count(added_to_cart =1 AND purchased IS NULL) AS abandonment 
FROM emr_data 
WHERE y='2017' AND m= '01' 
ORDER BY count(*) DESC 

Этот запрос дает:Ansi SQL запрос дает иррациональные результаты

all_addtocart abandonment 6563461 6850345

Каким all_addtocart ниже, чем заброшенности, когда оставление подсчитывает же значение с дополнительным contdition, что может только понизить счетчики.

Это на AWS Athena, который поддерживает ANSI SQL

+0

Я ожидал бы двух одинаковых чисел из этого запроса. Но если оптимизатор решает изменить порядок второго условия на «приобретенный номер IS NULL AND added_to_cart = 1», тогда «отказ» может быть больше, если некоторые значения в 'added_to_cart' равны NULL. –

+2

Не похож на действительный SQL-код для меня. Я ожидал бы что-то вроде 'CASE WHEN added_to_cart = 1 THEN 1 END', который требуется - многие продукты не будут принимать предикат непосредственно в' COUNT() '. –

+0

@PaulSpiegel - в каких логических системах обратный порядок двух предикатов в сочетании с 'AND' изменяет логический результат? –

ответ

1

Вы, видимо, работа с базой данных продукта, который будет счастливо неявно преобразовать предикатные значения в значения, которые могут быть COUNT ред и, если предположение Павла правильно , единственный способ получить результат, который вы указали, - это если COUNT и TRUE и FALSE результаты и только исключение из его числа UNKNOWN значений (иногда называемых NULL, но в большинстве продуктов эти две концепции не являются объединены вместе).

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

SELECT 
count(CASE WHEN added_to_cart=1 THEN 1 END) AS all_addtocart, 
count(CASE WHEN added_to_cart =1 AND purchased IS NULL THEN 1 END) AS abandonment 
FROM emr_data 
WHERE y='2017' AND m= '01' 
ORDER BY count(*) DESC 

Этим примеры выражение обеспечивает мы только делать COUNT сек против int значений, которые являются либо 1 (если предикат верен) или NULL ,


я постеснялся бы описать любой продукт, который делает это как «ANSI», но опять же, почти каждый реальный продукт базы данных не точно соответствует ANSI в любом случае.