MySQL查询-使用自连接查找最接近开始日期和结束日期的行
我有一个查询,它使用一个表来查找距离日期范围任意一端最近的账号列表的MySQL查询-使用自连接查找最接近开始日期和结束日期的行,mysql,mariadb,Mysql,Mariadb,我有一个查询,它使用一个表来查找距离日期范围任意一端最近的账号列表的收入列,即距离日期范围开始最近的行和距离结束最近的行 我提出了以下建议,但它似乎只适用于第一个帐号,而不适用于之后的任何帐号 SELECT a.acct_no, b.revenue AS first_value, b.created_at AS first_date, c.revenue AS second_value, c.created_at AS second_date FROM `revenue_figures` a
收入
列,即距离日期范围开始最近的行和距离结束最近的行
我提出了以下建议,但它似乎只适用于第一个帐号,而不适用于之后的任何帐号
SELECT a.acct_no,
b.revenue AS first_value, b.created_at AS first_date,
c.revenue AS second_value, c.created_at AS second_date
FROM `revenue_figures` a
LEFT JOIN (
SELECT `acct_no`, `revenue`, `created_at`
FROM `revenue_figures`
WHERE `created_at` BETWEEN '2017-02-28 00:00:00' AND '2017-03-31 23:59:59'
AND `acct_no` IN ('A123', 'A124')
GROUP BY `acct_no`, `revenue`, `created_at`
ORDER BY `created_at` ASC
LIMIT 1
) b ON a.acct_no = b.acct_no
LEFT JOIN (
SELECT `acct_no`, `revenue`, `created_at`
FROM `revenue_figures`
WHERE `created_at` BETWEEN '2017-02-28 00:00:00' AND '2017-03-31 23:59:59'
AND `acct_no` IN ('A123', 'A124')
GROUP BY `acct_no`, `revenue`, `created_at`
ORDER BY `created_at` DESC
LIMIT 1
) c ON a.acct_no = c.acct_no
WHERE a.`created_at` BETWEEN '2017-02-28 00:00:00' AND '2017-03-31
23:59:59'
AND a.`acct_no` IN ('A123', 'A124')
GROUP BY a.acct_no, first_value, first_date, second_value, second_date
这将产生以下结果,但表中有A124
账号的数字:
acct_no first_value first_date second_value second_date
A123 8990.00 2017-02-28 7364.80 2017-03-31 01:00:00
A124 NULL NULL NULL NULL
我认为该查询存在一个基本缺陷,因为我注意到,如果运行几次,就会生成不同的结果,例如:
acct_no first_value first_date second_value second_date
A123 8990.00 2017-02-28 NULL NULL
A124 NULL NULL 28361.76 2017-03-31 01:00:00
表格结构
id, acct_no, revenue, created_at
示例数据
1, A123, 8990.00, 2017-02-28 01:00:00
2, A123, 7364.80, 2017-03-31 01:00:00
3, A124, 17324.12, 2017-02-28 01:00:00
4, A124, 28361.76, 2017-03-31 01:00:00
(重新打开,因为OP的代码处理“dup”问题所讨论的内容。真正的问题是关于另一个问题。)
问题是,您需要两个账号中的最新一个,但随后限制1
,这会抛出其中一个账号。让我们首先关注一个子查询
我说你想要两行,每个账号一行,对吗?要做到这一点,您需要为每个账号查找一行,并且可能唯一的方法是使用两个选择的联合所有。。。订购人。。。限制1
。否分组依据
那么,现在你有了
LEFT JOIN
(
( SELECT ... acct_no = 'A123' ... LIMIT 1 )
UNION ALL
( SELECT ... acct_no = 'A124' ... LIMIT 1 )
)
首先让工会首次亮相,看看它是否得到了渴望的一对排
然后将其放入每个左连接中(尽管我不知道是否需要左连接),以查看大查询是否正常
其他一些提示
INDEX(acct_no, created_at)
使用此模式:
created_at >= '2017-03-01'
AND created_at < '2017-03-01' + INTERVAL 1 MONTH
您应该共享表结构和示例数据。。。我们无法仅通过查询来回答您的问题。嗨,Raymond,添加了一些示例数据,但不是实际的CREATE
或INSERT
语句。LIMIT 1
意味着您在每个子查询中只能得到一行。如果该行用于A123
,则不会获得A124
的任何数据。不是每个帐户都有一行。如果您想获得每个帐户最早和最新的行,请参阅“谢谢”,我们将进行查看。如果我从子查询中取出LIMIT 1
,我会得到问题所在日期范围内每个账号每天的结果。嗨,Rick,谢谢你重新打开并给出答案<代码>在
处创建是一个时间戳
列。日期是故意的,因为它是从前端输入的日期范围,所以计划是查找距离日期范围任意一端最近的行。将在明天的工作中对此进行尝试,通过查询确切的日期使其工作,但更希望它按照最初的预期工作。
GROUP BY acct_no