MySQL:从特定顺序显示每个组的第一个

MySQL: display first of each group from a specific order

我有两个 tables 字段和内容 table 看起来像这样(简化)。

fields Table

id    name
1     Field One
2     Field Two

content Table

id   field_id   status      content
1    1          draft       xxx
2    1          published   xxx
3    2          published   xxx

唯一吸引人的地方是与字段相关的内容有一个 "draft" 系统,每个字段都是独立的。

所以我检索了所有字段的草稿版本,它应该带来所有草稿,除了该字段没有草稿版本,在这种情况下它应该 return 已发布的版本。

(还有更多状态,为了简单起见,我只使用两个)。因此,当从示例 table 中检索时。结果应该是这样的:

id   field_id   status      content
1    1          draft       xxx
3    2          published   xxx

可以实现我想要的东西是这个

SELECT * FROM contents c1 WHERE id IN (
    SELECT id FROM contents c 
       WHERE (c.status = 'draft' OR c.status = 'published') 
            AND c.field_id = c1.field_id 
       ORDER BY FIELD(status, 'draft', 'published') LIMIT 1
);

唯一的问题是 MySQL 我使用的版本 (5.7.12) 似乎不支持 IN 中的限制。

This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'

嗯。这是一种使用聚合和 max(field()) 来识别适当版本的方法:

select c.*
from (select field_id, min(field(status, 'draft', 'published')) as min_field
      from contents
      group by field_id
     ) cf join
     contents c
     on c.field_id = cf.field_id and field(status, 'draft', 'published') = cf.min_field;

如果您想获取最新的草稿(如果不存在,则为最新发布的),您可以使用用户变量生成分区行号(根据 field_id 分区),所需顺序为:

select *
from (
select t.*,
    @rn :=  if(@field_id = field_id, 
                @rn + 1,
                if(@field_id := field_id, 1, 1)
                ) rn
from (
    select
    from content
    order by field_id,
        field(status, 'draft', 'published'),
        id desc
    ) t cross join (select @rn := 0, @field_id := -1) t2
) t where rn = 1;