0

我一直在处理这两个表:

文档

id    company_id    etc
=======================
1     2             x
2     2             x

版本

id    document_id   version    date_created    date_issued   date_accepted
==========================================================================
1     1             1          2013-04-29      2013-04-30    NULL
2     2             1          2013-05-01      NULL          NULL
3     1             2          2013-05-01      2013-05-01    2013-05-03

有一个页面我想列出所有文档及其属性。我想从每个文档中添加一个单独的状态。状态可以从对应Version的 s 拥有的最近日期推导出来。可能正在接受较旧的版本。

我要找的查询结果是这样的:

id    company_id    etc   status
==================================
1     2             x     accepted
2     2             x     created

我首先进行了一个查询,该查询结合了所有日期并在其旁边添加了一个状态。它按预期工作,当我添加 document_id 时,一切正常。

SELECT `status`
FROM (
    SELECT max(date_created) as `date`,'created' as `status` FROM version WHERE document_id = 1
    UNION
    SELECT max(date_issued),'issued' FROM version WHERE document_id = 1
    UNION
    SELECT max(date_accepted),'accepted' FROM version WHERE document_id = 1
    ORDER BY date DESC
    LIMIT 1
) as maxi

当我尝试将此查询合并为子查询时,我无法使其工作。

SELECT *, (
  SELECT `status` FROM (
    SELECT max(date_created) as `date`,'created' as `status`FROM version WHERE document_id = document.id
    UNION
    SELECT max(date_issued),'issued' FROM version WHERE document_id = document.id
    UNION
    SELECT max(date_accepted),'accepted' FROM version WHERE document_id = document.id
    ORDER BY date DESC
    LIMIT 1
  ) as maxi
) as `status`
FROM `document`

这会让我出错Unknown column 'document.id' in 'where clause'。所以我在 SO 上阅读并认为它根本无法达到该值offer.id,因为它是子查询中的子查询。因此,我尝试采用另一种方法并一次获取所有状态,以避免该WHERE语句并加入它们。我结束了下一个查询。

SELECT MAX(`date`),`status`, document_id
FROM (
    SELECT datetime_created as `date`, 'created' as `status`,document_id FROM `version`
    UNION
    SELECT datetime_issued, 'issued',document_id FROM `version`
    UNION
    SELECT datetime_accepted, 'accepted',document_id FROM `version`
) as dates
GROUP BY offer_id

这次没有错误,但我意识到它status不可能是正确的,因为它在GROUP BY. 我已经尝试过将两者结合起来,但这两个缺陷一直在阻碍我。任何人都可以建议如何在不更改我的数据库的情况下在单个查询中执行此操作吗?(我知道将日期保存在单独的表格中很简单)

4

3 回答 3

1

我没有测试过这个,但你可以这样做(你可能需要调整细节)

它基本上是从一个完全不同的角度来看它。

 select
    d.*,
    (CASE GREATEST(ifnull(v.date_created, 0), ifnull(v.date_issued,0), ifnull(v.date_accepted,0) ) 
      WHEN null THEN 'unknown'
      WHEN v.date_accepted THEN 'accepted'
      WHEN v.date_issued THEN 'issued'
      WHEN v.date_created THEN 'created'
      END) as status 
from document d
left join version v on 
    v.document_id = d.document_id and 
    not exists (select 1 from (select * from version) x where x.document_id = v.document_id and x.id <> v.id and x.version > v.version)
于 2013-05-03T11:47:16.600 回答
0
select Doc.document_id,Doc.company_id,Doc.etc,f.status
from Document Doc
inner join 
    (select Ver.document_id,
    case when Ver.date_accepted is not null then 'Accepted'
    when Ver.date_issued is not null then 'Issued'
    when Ver.date_created is not null then 'Created'
    end as status
from version Ver
inner join (
                select document_id,MAX(version) VersionId
                from version
                group by document_id
            )t on t.document_id=Ver.document_id 
where t.VersionId=Ver.version
)f on Doc.document_id=f.document_id

SQL小提琴

于 2013-05-03T12:21:00.600 回答
0

您能否标准化您的表格设计以将状态/日期移动到与版本不同的表格上?

如果不可能是这样的:-

SELECT Document.id, Document.company_id, Document.etc, CASE WHEN Sub1.status = 3 THEN 'accepted' WHEN Sub1.status = 2 THEN 'issued' WHEN Sub1.status = 1 THEN 'created' ELSE NULL END AS status
FROM Document
INNER JOIN (
    SELECT document_id, MAX(CASE WHEN date_accepted IS NOT NULL THEN 3 WHEN date_issued IS NOT NULL THEN 2 WHEN date_created IS NOT NULL THEN 1 ELSE NULL END) AS status 
    FROM Version
    GROUP BY document_id
) Sub1
ON Document.id = Sub1.document_id

子选择从版本表中获取任何文档的最高状态。每个可能版本的最高状态都作为一个数字返回,并且通过将其分组到文档 id 上,它将获得任何版本的最高状态。这与 Document 表和转换为文本描述的版本号的数字相结合。

于 2013-05-03T13:32:42.630 回答