mysql - 如何绕过子查询中对外部表的引用?

标签 mysql subquery aggregate-functions

我一直在处理这两个表:

文档

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

有一个页面,我想在其中列出所有文档及其属性。 我想从每个文档中添加一个状态。 状态可以从相应版本的最新日期得出。 有可能正在接受旧版本。

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

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`

这会给我带来错误“where 子句”中的未知列“document.id”。所以我在 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 期间丢失了。我尝试过将两者结合起来,但这两个缺陷一直阻碍着我。任何人都可以建议如何在单个查询中执行此操作而不更改我的数据库吗? (我知道将日期保存在单独的表中会很简单)

最佳答案

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

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

 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)

关于mysql - 如何绕过子查询中对外部表的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16357956/

相关文章:

mysql - 查询中的开始太多,或者这是 kosher?

MySql 查询 : include days that have COUNT(id) == 0 but only in the last 30 days

mysql - 使用 left join 和 sum 加速 mysql 查询

mysql - Kafka JDBC Source Connector 没有使用 sql 查询从 mysql 读取数据?

mysql - 我应该害怕还是拥抱数据库触发器?

java - 没有合适的驱动程序

activerecord - 获取 ActiveRecord 中每个组的最小值/最大值

mysql - 连接时更改一个表中的行值以匹配另一表中的行值

sql - SQL喜欢与子查询

sql - 使用产生两列的子查询删除(在 Postgresql 中)