我正在编写一个查询,根据某人是"高捐赠者"还是"低捐赠者"来提取联系人数据,我的查询运行良好,除了它将包括某人作为高捐赠者和低捐赠者,如果他们在这两个类别中,当我们真的只想将他们作为高捐赠者。
(例如:杰伊·史密斯在 6 月捐赠了 1000 美元,在 7 月捐赠了 50 美元。杰伊将被列为高捐赠者和低捐赠者。
为了解决这个问题,我正在尝试根据他们是否已经被发现是高捐赠者来排除联系人。我的原始查询将这些子查询合并在一起,但是当我尝试为各个子查询添加别名并在第二个子查询中引用 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
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
为零的捐助者。与其使用HAVING
我宁愿建议调整您的逻辑以使用 <(或>(而不是 <=(或>=(,BETWEEN
是它的别名。金额>
顺便说一句:你正在使用双引号 ("
(,你应该使用单引号 ('
((将字符串和日期文字括起来(。
您不能像这样为两个子查询添加别名,并在第二个子查询中使用第一个子查询。您可以尝试以下操作:
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)
更有效的方法是将第一个联合选择存储在临时表中并在联合中使用它,然后在第二个联合选择查询中使用相同的临时表来排除高捐赠者。