仅在连接表中选择具有一些where子句的最大值

时间:2014-01-17 11:43:08

标签: php mysql greatest-n-per-group

好吧,在我研究并尝试了多种方法(主要在stackoverflow上找到)后,我仍然没有得到它的工作。

我有一个像这样的mysql表(缩短了,时间当然是时间戳):

id docid wardid version approved endingtime
 1   1      1      1        1    5 days
 2   1      1      2        1    20 days
 3   1      1      3        0    40 days
 4   2      2      1        0    30 days
 5   2      2      2        1    50 days

以及其他两个表格,其中包含namedocid

wardid的值

现在,它想要的是选择所有未被批准或在特定结束时间内但仅在具有最高版本的行中的所有行(每个docid条目中只有一个)。所以在这个例子中我想只得到id为3的行 这听起来很简单,因为我写这个,但我完全失去了。不够,我的白痴抹去了所有的尝试(但最后一次):

SELECT MAX(dv.version), dv.docid, dv.id, dv.approved, dv.endingtime, d.name, w.name
FROM (doc_versions as dv
    LEFT JOIN docs as d ON d.id = dv.docid
    LEFT JOIN wards as w ON w.id = d.wardid
WHERE (approved < 1 AND ...)
OR (dv.endingtime < $time AND ...)
GROUP BY dv.docid

希望你能帮助我。我认为这是最糟糕的尝试(这让我昨天变得狂暴);)

编辑: 我的最后一次尝试似乎有效,不得不再尝试一下。

SELECT v1.docs_id, v1.id as docversion, v1.approved, v1.approver, d.name as docname, w.name as wardname, d.wards_id as wardsid, v1.validity_endtime as deadline, v1.creator
        FROM 
        (
            doc_versions v1
            LEFT JOIN docs as d ON d.id = v1.docs_id 
            LEFT JOIN wards as w ON w.id = d.wards_id
        ) 
        INNER JOIN
        (
          SELECT MAX(version) version, docs_id
          FROM doc_versions
          GROUP BY docs_id
        ) v2
          ON v1.version = v2.version
          AND v1.docs_id = v2.docs_id
        WHERE (approved < 1 AND approver = ".$userid.($wardid > 0 ? ' AND wardsid = '.$wardid : '').")
        OR (v1.validity_endtime < $time AND creator = ".$userid.($wardid > 0 ? ' AND wardsid = '.$wardid : '').")";

1 个答案:

答案 0 :(得分:0)

这样的事情应该做:

SELECT *
FROM doc_versions dv1
INNER JOIN (
    SELECT id, MAX(version) version
      FROM doc_versions
     WHERE (approved = 0 OR endingtime < $time ...)
     GROUP BY id
) dv2 ON dv1.id = dv2.id AND dv2.version = dv1.version

在子查询中,您构建一个包含每个id和最大有效版本的表;在外部查询中,您将加入关于这两个值的初始表。