这是对上一个问题的跟进: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语句是什么?
答案 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