预订GROUP BY语句

时间:2016-09-14 20:21:59

标签: mysql sql

这是对上一个问题的跟进:GROUP BY ordering

我有以下sql表和数据:http://sqlfiddle.com/#!9/81c3b6/2/0

基本的无序SQL语句是:

platform_type_id

我希望为表格中的每个territory_id='US'获取一个条目,并优先选择territory_id='US'。也就是说,如果条目存在GROUP BY,我想在{{1}}语句中抓住那个条目。

返回GROUPed by语句的首选SQL语句是什么?

3 个答案:

答案 0 :(得分:3)

在MySQL中,最安全的方法可能涉及变量:

select im.*
from (select im.*,
             (@rn := if(@p = platform_type_id, @rn + 1,
                        if(@p := platform_type_id, 1, 1)
                       )
             ) as rn
      from main_itemmaster im cross join
           (select @rn := 0, @p := '') params
      order by platform_type_id, (territory_id = 'US') desc
     ) im
where rn = 1;

不涉及使用MySQL(mis)功能,该功能允许聚合查询的SELECT中的列未聚合而不在GROUP BY中。

Here是一个SQL小提琴,显示它正常工作。

编辑:

关于变量评估顺序的主题。来自documentation

  

作为一般规则,除了SET语句之外,你永远不应该   为用户变量赋值并读取其中的值   声明。例如,要增加变量,这没关系:

SET @a = @a + 1;
     

对于其他语句,例如SELECT,您可能会得到结果   期待,但这不能保证。在以下声明中,您   可能会认为MySQL会首先评估@a然后做一个   第二个任务:

SELECT @a, @a:=@a+1, ...;
     

但是,涉及用户的表达式的评估顺序   变量未定义。

从技术上讲,上面的代码在同一个语句中读取变量,但它也在同一个表达式中。 if()(以及我有时也使用的case)的语义保证了表达式的评估顺序。

答案 1 :(得分:2)

试试:

SELECT * FROM main_itemmaster
WHERE territory_id LIKE 'US'
GROUP BY platform_type_id

UNION

SELECT * FROM main_itemmaster
WHERE platform_type_id NOT IN (
  SELECT platform_type_id FROM main_itemmaster
  WHERE territory_id LIKE 'US')
GROUP BY platform_type_id

答案 2 :(得分:0)

这应该有效

SELECT territory_id, platform_type_id, store_url 
FROM main_itemmaster
GROUP BY platform_type_id
ORDER by if(territory_id ='US',1,99) asc

以上是

的sqlfiddle