Я пишу запрос, чтобы вытащить контактные данные на основе того, является ли кто-то "высоким донором" или "низким донором", и мой запрос работает отлично, за исключением того, что он будет включать кого-то как highDonor и lowDonor, если они находятся в обе категории, когда мы действительно хотим просто включить их в качестве highDonor.
(Например: Джей Смит пожертвовал 1000 долларов в июне и 50 долларов в июле. Jay будет указан как highDonor, так и lowDonor.)
Чтобы исправить эту проблему, я пытаюсь исключить контакты из lowDonors на основе, если они уже были признаны highDonors. Мой исходный запрос объединил эти подзапросы, но когда я пытаюсь выполнить псевдоним отдельных подзапросов и ссылаться на highDonors во втором подзапросе, я получаю сообщение об ошибке.
(Примечание: это сокращенная версия полного запроса, который фокусируется на частях, которые вызывают ошибку.)
Это ошибка, которую я получаю: #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'highDonors.contactId) as lowDonors ) as highAndLowDonors ' at line 23
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'highDonors.contactId) as lowDonors ) as highAndLowDonors ' at line 23
SELECT DISTINCT
...
FROM
((
SELECT DISTINCT contactid,
"highDonor" AS highorlowdonor
FROM donation
WHERE donationdate > "2015-07-03"
AND donationamount BETWEEN 100 AND 9999.99)
AS highdonors
UNION ALL
(
SELECT DISTINCT contactid,
"lowDonor" AS highorlowdonor
FROM donation
WHERE donationdate > "2015-07-03"
AND donationamount BETWEEN 1 AND 99.99
WHERE contactid NOT IN highdonors.contactid)
AS lowdonors )
AS highandlowdonors
...
Любые мысли о том, что вызывает здесь ошибку? Могу ли я использовать два подзапроса, подобных этому, и использовать первый внутри второго?
Вы не можете использовать результат из первого запроса во втором, если вы не повторите первый запрос.
Но вы можете переписать запрос в группу contactid
и получить максимальное количество donationamount
. Положите свою логику в CASE
глядя на этот максимум.
SELECT contactid,
CASE
WHEN max(donationamount) BETWEEN 100 AND 9999.99
THEN 'highDonor'
WHEN max(donationamount) BETWEEN 1 AND 99.99
THEN 'lowDonor'
END highorlowdonor
FROM donation
WHERE donationdate > '2015-07-03'
GROUP BY contactid
HAVING CASE
WHEN max(donationamount) BETWEEN 100 AND 9999.99
THEN 'highDonor'
WHEN max(donationamount) BETWEEN 1 AND 99.99
THEN 'lowDonor'
END IS NOT NULL;
(Примечание. Без HAVING
это будет включать доноров, которые пожертвовали сумму <1 или 99,99 <сумма <100 или сумму> 9999.99, но с highorlowdonor
указателя на highorlowdonor
. Вместо использования HAVING
я бы скорее рекомендовал адаптировать вашу логику к использованию <(или>), а не <= (или> =), который BETWEEN
является псевдонимом.)
И BTW: вы используете двойные кавычки ("
), где вы должны использовать одинарные кавычки ('
) (чтобы вложить строки и литералы даты).
Вы не можете выровнять два подзапроса, как это, и использовать первый внутри второго. Вы можете попробовать следующее:
SELECT DISTINCT contactid,
"highDonor" AS highorlowdonor
FROM donation
WHERE donationdate > "2015-07-03"
AND donationamount BETWEEN 100 AND 9999.99)
AS highdonors
UNION ALL
SELECT DISTINCT contactid,
"lowDonor" AS highorlowdonor
FROM donation
WHERE donationdate > "2015-07-03"
AND donationamount BETWEEN 1 AND 99.99
AND contactid NOT IN (select contact_id
FROM donation
WHERE donationdate > "2015-07-03"
AND donationamount BETWEEN 100 AND 9999.99)
Более эффективным способом было бы сохранить первый выбор union в таблице temp и использовать его в объединении, а затем использовать ту же самую временную таблицу во втором запросе выбора union, чтобы исключить высокие доноры.
HAVING
, чтобы исключить нули. Сможете ли вы обновить свой ответ, чтобы включить это? Это было бы очень полезно!