具有特定条件的 MySQL GROUP BY

Posted

技术标签:

【中文标题】具有特定条件的 MySQL GROUP BY【英文标题】:MySQL GROUP BY with specific condition 【发布时间】:2021-01-07 10:35:37 【问题描述】:

我正在使用mysql 5.5。这是我的查询,第一部分显示有关公司及其车辆的信息,第二部分仅显示公司信息。

我做了UNION 部分,因为一些smallClients 没有任何车辆,并且由于在第一部分join 有车辆,那些没有出现。

有什么问题,第一部分和第二部分的一些寄存器具有相同的 smallClient,并且由于在车辆部分我已经显示了公司信息,我想分组,前提是它们是相同的 idClient 和相同的部门,并且 numberPlate 不为 null(如果为 null 没关系,我只想删除那些已经显示在车辆部件中的冗余原因信息的寄存器)。

有些公司也可以有多个车牌,并且不能分组,因为每个车牌都有自己的文档(这个查询比真实的小)。

现在的结果是什么样的:

idClient  company          department    numberplate
3345      TONY FERGUSON    Commercial    null
3345      TONY FERGUSON    Financial     null
3345      TONY FERGUSON    Commercial    8453JVD

在这个例子中,第一个寄存器应该没有了,因为这个客户有一个 numberPlate,并且与相同部门的寄存器(第一个)是多余的,因为第三个寄存器显示相同。

另一个例子:

idClient  company          department               numberplate
1267      TERRY SL         Distribution - France    null
1267      TERRY SL         Distribución - France    6381JHZ
1267      TERRY SL         Forwarding UK            null
1267      TERRY SL         Forwarding UK            6381JHZ

在这种情况下,第一个和第三个寄存器应该消失了,希望我解释得当。

这是我的查询:

select  
    idClient as "IdClient",
    Company  as "Company",         
    if (Department is null, "", Department) as "Department",
    Numberplate,               
 from      
    (select
         sc.idClient as idclient,
         sc.businessname as company,     
         d.name as department,          
         v.numberplate as numberPlate,               
    from entity_type et
         join bigClient bc on bc.idClient=et.idClient
         join smallClient sc on sc.idclient=bc.idClientAssociated
         join clientVehicle cv on cv.idClientVehicle=sc.idClientVehicle
         join vehicle v on v.idVehicle=cv.idVehicle    
         join active_vehicle av on av.idEntityType=et.idEntityType and av.idClientVehicle=cv.idClientVehicle 
         left join department d on d.idDepartment=et.idDepartment   
         where bc.idClient=1234   
    UNION
    select 
         c.idClient as idclient,
         c.businessname as empresavehicle,      
         cd.name as departament,      
         null as matricula,          
        from entity_type et
         join bigClient bc on bc.idClient=et.idClient
         join smallClient sc on sc.idclient=bc.idClientAssociated
         join active_c ac on ac.idEntityType=et.idEntityType and ac.idBigClient=bc.idBigClient   
         left join department d on d.idDepartment=et.idDepartment        
         where bc.idClient=1234) t
    order by company,numberplate;

【问题讨论】:

是否任何公司都可以拥有多个不为空的numberplate 是的,它也可能发生,我没有指定它不好。 所以如果我们有 3 条记录的结果,其中 3 条为空,另外 2 条不同 numberplate,我们应该只删除空记录,对吧? 没错,但是在这种情况下我们会有 4 个结果,因为每个 numberPlate 寄存器都会有它的“唯一公司信息”寄存器。 欢迎来到 SO。请看Why should I provide an MCRE for what seems to me to be a very simple SQL query 【参考方案1】:

可以使用解析函数count如下:

select * from
(select  
    idClient as "IdClient",
    Company  as "Company",         
    if (Department is null, "", Department) as "Department",
    Numberplate,
    count(Numberplate) over (partition by idClient,company,department) as cnt
  from
    .... rest of your query ....
) t
where cnt = 0 or (cnt>0 and Numberplate is not null)

【讨论】:

over 部分给了我错误,我想我没有合适的版本来做到这一点。如果我select version(); 结果是5.5.62-0ubuntu0.14.04.1 我的 SQL 版本有什么办法吗? @Slava Rozhnev 提出了一种方法,但我仍然需要为每个车牌使用不同的寄存器。【参考方案2】:

@Popeye 解决方案应该可以在 MySQL 8.o 或更高版本中运行,对于 MySQL 5.x,我接下来可以提出建议:

select  
    idclient as "IdClient",
    company  as "Company",         
    if (department is null, "", department) as "Department",
    group_concat(numberplate) as ,
 from      
    (select
         sc.idClient as idclient,
         sc.businessname as company,     
         d.name as department,          
         v.numberplate as numberplate,               
    from entity_type et
         join bigClient bc on bc.idClient=et.idClient
         join smallClient sc on sc.idclient=bc.idClientAssociated
         join clientVehicle cv on cv.idClientVehicle=sc.idClientVehicle
         join vehicle v on v.idVehicle=cv.idVehicle    
         join active_vehicle av on av.idEntityType=et.idEntityType and av.idClientVehicle=cv.idClientVehicle 
         left join department d on d.idDepartment=et.idDepartment   
         where bc.idClient=1234   
    UNION
    select 
         c.idClient as idclient,
         c.businessname as company,      
         cd.name as departament,      
         null as numberplate,          
        from entity_type et
         join bigClient bc on bc.idClient=et.idClient
         join smallClient sc on sc.idclient=bc.idClientAssociated
         join active_c ac on ac.idEntityType=et.idEntityType and ac.idBigClient=bc.idBigClient   
         left join department d on d.idDepartment=et.idDepartment        
         where bc.idClient=1234) t
    group by idClient, Company, Department
    order by company,numberplate;

这个查询应该有一个限制 - 如果不同的车牌它返回一个连接字符串

【讨论】:

哦...那么就没有办法将车牌分开吗?因为每个车牌都有自己的文档,我删除了该部分以使查询更小。 也许我们可以做某种类型的group by idClient, Company, Department 后跟一些having 条件,只有在不超过一个号码牌的情况下才能进行某种分组。

以上是关于具有特定条件的 MySQL GROUP BY的主要内容,如果未能解决你的问题,请参考以下文章

MySQL:条件 MIN() 与 GROUP BY

使用 group_by 后根据条件转换哈希值

MySQL分组条件,group by order by limit 顺序

MySQL 条件 SUM 使用 GROUP BY 和 DISTINCT

mysql group by,两个条件,限制1

具有日期范围条件的 Group By 和 SUM 的 sql