我正在使用两个表(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

10-07 12:49
查看更多