我一直在处理这两个表:
文献
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
具有的最新日期派生。
可能会接受旧版本。
我正在寻找的查询结果是这样的:
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
期间丢失了。我已经尝试了两者的组合,但这两个缺点一直阻碍着我。任何人都可以建议如何在单个查询中执行此操作而不更改我的数据库? (我知道将日期保存在一个单独的表中只是一件事)
答案 0 :(得分: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)
答案 1 :(得分: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 Fiddle 强>
答案 2 :(得分: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表以及转换为文本说明的版本号的编号连接在一起。