我正在使用两个表(ft_form_1&ft_field_options)。
ft_form_1
submission_id facility_id admits reporting_date timestamp
1 111A 1 2017-03-31 00:00 2017-03-31 17:53:17
2 222B 3 2017-03-31 00:00 2017-03-31 18:42:20
3 333C 6 2017-03-31 00:00 2017-03-31 19:27:47
4 222B 0 2017-04-01 00:00 2017-04-01 18:12:12
5 333C 4 2017-03-31 00:00 2017-04-01 19:38:25
6 333C 5 2017-04-01 00:00 2017-04-01 20:31:16
ft_field_options
list_id option_order option_value option_name
1 4 111A New York
1 2 222B Chicago
1 1 333C Boston
1 3 444D Miami
我现在得到的是:
facility_id option_name option_order admits reporting_date timestamp
111A New York 3 1 2017-03-31 00:00 2017-03-31 17:53:17
我想要得到什么:
facility_id option_name option_order admits reporting_date timestamp
111A New York 3 1 2017-03-31 00:00 2017-03-31 17:53:17
222B Chicago 2 3 2017-03-31 00:00 2017-03-31 18:42:20
333C Boston 1 4 2017-03-31 00:00 2017-04-01 19:38:25
通过下面的查询,我试图从指定的'reporting_date'获取所有提交的列表,其中每个'facility_id'的'list_id'等于1。如果在同一'reporting-date'上发送了多个提交,则仅将显示具有最新“时间戳”的提交。
问题:我相信此查询未按我希望的顺序运行。似乎查询正在为表中的每个“ facility_id”查找最大“时间戳”,然后进行过滤以仅显示具有指定“ reporting_date”的提交。我希望这种情况以相反的顺序发生-查询被过滤为仅显示具有指定“ reporting_date”的提交,然后将列表缩小范围以仅显示每个“ facility_id”的最大“时间戳”。从上面的示例中可以看到,芝加哥和波士顿被排除在外,因为第二天它们的时间戳更加新。
我是MYSQL新手,因此对您有所帮助!我最初从以下链接获得了MAX子查询的概念:http://www.w3resource.com/sql/aggregate-functions/max-date.php
SELECT t1.facility_id, t1.admits, t1.reporting_date, t1.timestamp,
t2.option_name, t2.option_order
FROM ft_form_1 t1
LEFT JOIN ft_field_options t2
ON (t1.facility_id = t2.option_value AND t2.list_id = 1)
WHERE (DATE_FORMAT(t1.reporting_date,'%m/%d/%Y') =
DATE_FORMAT(NOW() - INTERVAL 1 DAY,'%m/%d/%Y')) AND (timestamp=(
SELECT MAX(timestamp)
FROM ft_form_1
WHERE facility_id = t1.facility_id))
ORDER BY option_order ASC
*想象一下今天是2017年4月1日,上面的查询开始工作。
最佳答案
答案是使用结构化查询语言的结构化部分。 SQL是一种声明性语言,而不是过程性语言,因此考虑其执行顺序可能会令人困惑。
首先,您要查找list_id为1的行。让我们进行查询以获取该行。请注意,使用JOIN
而不是LEFT JOIN
:我们不需要不匹配的元素。 (http://sqlfiddle.com/#!9/8bdc3c/1/0)
SELECT t1.*
FROM ft_form_1 t1
JOIN ft_field_options t2
ON t1.facility_id = t2.option_value
AND t2.list_id = 1
接下来,我们需要找到每个机构在每个报告日期的最后提交的时间戳。 (http://sqlfiddle.com/#!9/8bdc3c/3/0)
SELECT MAX(timestamp) timestamp,
reporting_date reporting_date,
facility_id
FROM ft_form_1
GROUP BY reporting_date, facility_id
这些子查询是一个不错的选择,因为它们很容易测试。
最后,我们将这两个子查询结合在一起,以获得我们想要的东西。 (http://sqlfiddle.com/#!9/8bdc3c/6/0)
SELECT a.*
FROM (
SELECT t1.*
FROM ft_form_1 t1
JOIN ft_field_options t2
ON t1.facility_id = t2.option_value
AND t2.list_id = 1
) a
JOIN (
SELECT MAX(timestamp) timestamp,
reporting_date reporting_date,
facility_id
FROM ft_form_1
GROUP BY reporting_date, facility_id
) b ON a.facility_id = b.facility_id
AND a.timestamp = b.timestamp
AND a.reporting_date = b.reporting_date
技巧是在
GROUP BY
子查询中,该子查询可找到每个报告日期的最后一个时间戳。现在,您的表中有一个commit_id。如果那个commit_id是自动递增的,则可能是每个设施中用于报告数据的最大commit_id值是您想要的。如果是这样,则可以大大简化查询。
这将使您获得与您想要的提交相对应的submitting_id
SELECT MAX(submission_id)
FROM ft_form_1
GROUP BY reporting_date, facility_id
您可以像这样将其连接到主表,以获得所需的结果。 (http://sqlfiddle.com/#!9/8bdc3c/10/0)
SELECT t1.*
FROM ft_form_1 t1
JOIN ft_field_options t2 ON t1.facility_id = t2.option_value
AND t2.list_id = 1
JOIN (
SELECT MAX(submission_id) submission_id
FROM ft_form_1
GROUP BY reporting_date, facility_id
) q ON t1.submission_id = q.submission_id