Mysql 按顺序分组-选择与查看

Mysql 按顺序分组-选择与查看,mysql,Mysql,我得到了一些1:N的产品表及其图像表。为简单起见,只需: create table t_Product( ID int not null, Name varchar(255), primary key (ID) ); create table t_Images( ID int not null, PID int not null, IsDefault int, primary key (ID), foreign key (PID) references t_Product (ID) ); ins

我得到了一些1:N的产品表及其图像表。为简单起见,只需:

create table t_Product(
ID int not null,
Name varchar(255),
primary key (ID)
);
create table t_Images(
ID int not null,
PID int not null,
IsDefault int,
primary key (ID),
foreign key (PID) references t_Product (ID)
);
insert into t_Product (ID, Name) values (1, 'test1');
insert into t_Product (ID, Name) values (2, 'test2');
insert into t_Images (ID, PID, IsDefault) values (1, 1, 1);
insert into t_Images (ID, PID, IsDefault) values (2, 1, 0);
insert into t_Images (ID, PID, IsDefault) values (3, 2, 0);
insert into t_Images (ID, PID, IsDefault) values (4, 2, 1);
现在,我做了一个选择,它完全符合我的需要,从每个产品中选择默认图像或第一个图像:

select
    I.*
from
(
select
    ID,
    PID,
    IsDefault
from
    t_Images
order by
    PID asc,
    IsDefault desc,
    ID asc
) I
group by
    I.PID

ID  PID IsDefault
1   1   1
4   2   1
现在,我从“内部选择”创建一个视图:

create view v_Images
as
select
    ID,
    PID,
    IsDefault
from
    t_Images
order by
    PID asc,
    IsDefault desc,
    ID asc 
但选择此视图不适用于按以下方式分组时的排序:

select
    VI.*
from
    v_Images VI
group by
    VI.PID

ID  PID IsDefault
1   1   1
3   2   0
但如果我先从“选择自”视图中选择,然后再选择“分组依据”,它会再次工作:

select
    VI2.*
from
(
    select
        VI.*
    from
        v_Images VI
) VI2
group by
    VI2.PID

ID  PID IsDefault
1   1   1
4   2   1
有人能给我解释一下,为什么分组选择的结果与视图不同,为什么它在双选视图上再次工作?

这是您的问题:

select I.*
from (select ID, PID, IsDefault
      from t_Images
      order by PID asc, IsDefault desc, ID asc
     ) I
group by I.PID;
虽然这不是一个不常见的公式,但它使用了MySQL明确警告不要使用的构造。以下是相关部分的全文重点是我的:

要使查询合法,必须从 在GROUPBY子句中选择list或NAME

MySQL扩展了GROUPBY的使用,以便选择列表可以引用 GROUP BY子句中未命名的未聚合列。这意味着 前面的查询在MySQL中是合法的。您可以使用此功能 通过避免不必要的列排序和 分组。但是,这主要是在每个 未在GROUP BY中命名的未聚合列对于每个列都是相同的 组服务器可以从每个组中自由选择任何值,因此 除非它们相同,否则选择的值是不确定的

因此,尽管查询似乎可以工作,但文档警告不要这样做。我认为这种做法不好。另外,这是一个只在MySQL中工作的东西。其他数据库不允许此构造。而且,ANSI也有类似的ish功能,涉及具有功能依赖性的列,您可能会面临未来版本的MySQL将支持此合理功能的风险,从而使此方法无效

我的建议是使用一种合理的方法,这种方法不仅在MySQL中表现良好,而且符合ANSI标准。比如:

select ti.*
from t_Images ti
where not exists (select 1
                  from t_images ti2
                  where ti2.pid = ti.pid and
                        (ti2.IsDefault > ti.IsDefault or
                         (ti2.IsDefault = ti.IsDefault and
                          ti2.Id < ti.Id
                         )
                        )
                 )
设置sql_模式='ONLY_FULL_GROUP_BY';
select ti.*
from t_Images ti
where not exists (select 1
                  from t_images ti2
                  where ti2.pid = ti.pid and
                        (ti2.IsDefault > ti.IsDefault or
                         (ti2.IsDefault = ti.IsDefault and
                          ti2.Id < ti.Id
                         )
                        )
                 )
select pid, max(IsDefault) as IsDefault,
       substring_index(group_concat(id order by isDefault desc id asc), ',', 1) as id
from ti_images
group by pid;