【问题标题】:Join with Group By & Order by using Case in MySQL在 MySQL 中使用 Case 加入 Group By & Order
【发布时间】:2016-06-11 14:15:11
【问题描述】:

为什么这个查询不起作用?是因为 order by 和 group by 的组合吗?

一个表是广告,另一个是订阅,第三个是服务,第四个是服务和位置之间的多对多关系(位置是应该显示广告的位置)。

我想要的是先订购存储在具有位置 2 的广告表中的广告,然后是那些没有定义位置的广告,然后是位置 1(此订单是通过程序生成的)

广告表:
id、名称、subscription_id

订阅表:
subscription_id、service_id、日期、付费等...

service_locations 表:
service_idlocation_id

你可以看到在这种情况下有第四张桌子,但这并不重要


查询:

select adverts.id, GROUP_CONCAT(service_locations.location_id) AS locations from adverts 
    left join subscriptions 
        on adverts.subscription_id = subscriptions.id
    left join service_locations 
        on service_locations.service_id = subscriptions.service_id
    group by adverts.id
    order by case service_locations.location_id 
        when 2 then 1 
        when 1 then 3 
        else 2 
    end


预期结果:

+----+-----------+
| id | locations |
+----+-----------+
|  1 | 2         |
|  3 | 1,2       |
|  2 | null      |
+----+-----------+


我实际得到的(第三行的位置为 2,但它位于 null 之后):

+----+-----------+
| id | locations |
+----+-----------+
|  1 | 2         |
|  2 | null      |
|  3 | 1,2       |
+----+-----------+

【问题讨论】:

    标签: mysql join group-by sql-order-by case


    【解决方案1】:

    我找到了一个解决方案,order by 必须在 group by 之前执行,这不是默认行为,更多关于该行为在这里:https://stackoverflow.com/a/14771322/4329156)(必须使用子查询)

    所以,查询应该是这样的

    select *, GROUP_CONCAT(location_id) as locations from (
        select adverts.id AS id, service_locations.location_id AS location_id from adverts 
        left join subscriptions 
            on adverts.subscription_id = subscriptions.id
        left join service_locations 
            on service_locations.service_id = subscriptions.service_id
        order by case service_locations.location_id 
            when 2 then 1 
            when 1 then 3 
            else 2 
        end
        ) as table 
        group by table.id
        order by case table.location_id 
            when 2 then 1 
            when 1 then 3 
            else 2 
        end
    

    【讨论】:

      【解决方案2】:

      当您使用group by 时,所有不在group by 中的列都应该具有聚合函数。所以,我认为你打算这样:

      select a.id, GROUP_CONCAT(sl.location_id) AS locations
      from adverts a left join
           subscriptions s
           on a.subscription_id = s.id left join
           service_locations sl
           on sl.service_id = s.service_id
      group by a.id
      order by max(case sl.location_id 
                     when 2 then 1 
                     when 1 then 3 
                     else 2 
                   end);
      

      我不确定max() 是否是您真正需要的,但您确实需要一个聚合函数。这特别产生了问题中的输出:

      order by (case min(sl.location_id)
                     when 2 then 1 
                     when 1 then 2
                     else 3
                 end);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-18
        • 2013-01-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多