[英]subquery in where clause (mysql)
SELECT d.userID, (d.amountSuccessfulDeposits), (d.numberSuccessfulDeposits), cl.notes, d.asofdate, cl.send_date
FROM campaign_list cl
INNER JOIN deposit d
on d.userid = cl.userid
WHERE cl.send_date > date(CURDATE()) - INTERVAL 7 DAY
AND cl.send_date < date(CURDATE()) - INTERVAL 1 DAY
AND d.asofdate > date(CURDATE()) - INTERVAL 7 DAY
AND d.asofdate < date(CURDATE()) - INTERVAL 1 DAY
and cl.notes in ('report11', 'report12', 'report13', 'report14', 'report15')
and d.asofdate > cl.send_date
用户ID输入广告系列后(报告11-15),查询会计算存款数量。 “send_date”是用户ID输入广告系列的日期。 但是,如果用户ID进一步推进到另一组广告系列(报告16-20),则在进入第二组广告系列(16-20)后进行的存款不应计入第一组广告系列(11 - 15)查询总计。
例:
Bob在1/20上输入报告11
鲍勃在1/21存款100美元
鲍勃在1/24输入报告16
鲍勃在1/25存款500美元
因此,上述查询只应为Bob返回100美元。
userID; amountSuccessfulDeposits; numberSuccessfulDeposits; notes; asofdate; send_date
2575192; 100.00; 1; report11 ;2016-01-21 ; 2016-01-20
以下查询无效
SELECT d.userID, (d.amountSuccessfulDeposits), (d.numberSuccessfulDeposits), cl.notes, d.asofdate, cl.send_date
FROM campaign_list cl
INNER JOIN deposit d
on d.userid = cl.userid
WHERE cl.send_date > date(CURDATE()) - INTERVAL 7 DAY
AND cl.send_date < date(CURDATE()) - INTERVAL 1 DAY
AND d.asofdate > date(CURDATE()) - INTERVAL 7 DAY
AND d.asofdate < date(CURDATE()) - INTERVAL 1 DAY
and cl.notes in ('report11', 'report12', 'report13', 'report14', 'report15')
and d.asofdate > cl.send_date
AND (
(SELECT (ocl.send_date)
FROM campaign_list ocl
WHERE ocl.userID = cl.userID
and ocl.notes in ('report16', 'report17', 'report18', 'report19', 'report20')
) > d.asofdate
)
我会使用内联视图来获取后续广告系列的“最早”的send_date。 (目前尚不清楚特定广告系列之间是否存在任何关系。如果Bob进入任何广告系列16-20,那么该广告系列的send_date将是以前所有广告系列的“截止”11-15)
如果没有完全理解规范,我有点不愿意建议一个“适用于你”的查询。
但基于给定的查询,我会做这样的事情:
SELECT d.userid
, d.amountSuccessfulDeposits
, d.numberSuccessfulDeposits
, cl.notes
, d.asofdate
, cl.send_date
FROM campaign_list cl
/ *在这里,我将为每个用户ID创建一个内联视图,该视图从后续广告系列16-20中获取“最早的” send_date
。 我做了一个外部联接到这个集合,像这样* /
LEFT
JOIN ( -- inline view to get earliest send_date
SELECT ocl.userid
, MIN(ocl.send_date) AS min_send_date
FROM campaign_list ocl
WHERE ocl.notes IN ('report16'
,'report17'
,'report18'
,'report19'
,'report20'
)
GROUP BY ocl.userid
) oc
ON oc.userid = cl.userid
/ *有了这个,我们将从sent_date
的后续广告系列中获得“最早的” sent_date
。 现在,这与cl
广告系列中的行相关联。 现在,我们可以加入deposit
表。 我的偏好是将d
列的所有条件放入连接的ON
子句,而不是WHERE
子句* /
JOIN deposit d
ON d.userid = cl.userid
AND d.asofdate > cl.send_date
AND d.asofdate > DATE(NOW()) + INTERVAL -7 DAY
AND d.asofdate < DATE(NOW()) + INTERVAL -1 DAY
/ *现在这里的诀窍...... * /
AND d.asofdate <= IFNULL(oc.min_send_date,d.asofdate + INTERVAL 1 DAY)
包括限制来自后续广告系列中最早的send_date
之后或之后具有asofdate
deposit d
行的条件。 棘手的部分是我们需要OR条件,当没有跟随竞选活动时,最早的send_date
将为NULL。 如果oc.min_send_date
的值不是NULL,那么我们只使用它。 如果它是NULL,我们替换一个不会限制从d
返回行的值。 大于d.asofdate
的值将起作用。
我正在使用<=
(小于或等于)测试。 如果我们只是用一个<
测试,这似乎是一个deposit
与asofdate
是在同一天send_date
将是一个无人区......它不会为先前的活动返回,因为我们已经有了一个>
(大于)限制d.asofdate > cl.send_date
。
那么WHERE
子句对cl
* /中的行有限制
WHERE cl.send_date > DATE(NOW()) + INTERVAL -7 DAY
AND cl.send_date < DATE(NOW()) + INTERVAL -1 DAY
AND cl.notes IN ('report11'
,'report12'
,'report13'
,'report14'
,'report15'
)
这就是我要采取的方法。
或者,在相关条款中的相关子信息
如果有一些原因你需要在WHERE
子句中包含一个从属子查询...你可以把它写成一个EXISTS
谓词...检查是否有任何跟随广告的发送方式早于asofdate,例如
AND NOT EXISTS ( SELECT 1
FROM campaign_list ocl
WHERE ocl.userID = cl.userid
AND ocl.send_date < d.asofdate
AND ocl.notes IN ('report16'
,'report17'
,'report18'
,'report19'
,'report20'
)
)
或者,如果有某些原因需要对查询的返回进行标量比较(执行小于/大于比较),则子查询的返回必须是标量...查询必须返回单个列并返回(最多)一行。
要确保返回的行不超过一行,可以使用聚合(例如MIN()
,或者可以使用LIMIT
子句。并且您需要准备好处理如果没有找到行将返回的NULL值。
AND ( d.asofdate <= IFNULL( ( SELECT ocl.send_date
FROM campaign_list ocl
WHERE ocl.userID = cl.userid
AND ocl.send_date >= d.asofdate
AND ocl.notes IN ('report16'
,'report17'
,'report18'
,'report19'
,'report20'
)
ORDER BY ocl.send_date ASC
LIMIT 1
)
, d.asofdate
)
MySQL中可能存在一些限制, WHERE
子句中可能不允许使用依赖子查询。 你肯定可以在HAVING
子句中得到它。 但是,在GROUP BY操作之后,HAVING子句几乎在语句执行中被评估。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.