这是我的查询
(SELECT * FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%only three doors%" OR `joke` LIKE "%only three doors%") ORDER BY `ups` DESC,`downs` ASC)
UNION
(SELECT * FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%only%" OR `joke` LIKE "%only%") ORDER BY `ups` DESC,`downs` ASC)
UNION
(SELECT * FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%three%" OR `joke` LIKE "%three%") ORDER BY `ups` DESC,`downs` ASC)
UNION
(SELECT * FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%doors%" OR `joke` LIKE "%doors%") ORDER BY `ups` DESC,`downs` ASC)
LIMIT 0, 30
由于某些原因,它似乎没有按顺序排序......它只是按照它们在数据库中自然的顺序将结果扔回去。
当我将其剪切为只有一个查询时,它工作正常,但除此之外,它似乎忽略了它。
我也不想按整个结果排序,或者我会放LIMIT 0,30 Order By blah
答案 0 :(得分:24)
来自MySQL documentation:
...使用ORDER BY表示各个SELECT语句 没有关于行在最终结果中出现的顺序 因为UNION默认生成一组无序行。
基本上,联盟中ORDER
唯一有用的时间是你使用LIMIT
。
所以,如果您的查询是这样的:
(SELECT * FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%only three doors%" OR `joke` LIKE "%only three doors%") ORDER BY `ups` DESC,`downs` ASC LIMIT 10)
UNION ...
然后,您将看到将根据该订单返回的前十条记录,但它们不一定按顺序显示。
<强>更新强>
试试这个 -
(SELECT *, 1 as ob FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%only three doors%" OR `joke` LIKE "%only three doors%") )
UNION
(SELECT *, 2 as ob FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%only%" OR `joke` LIKE "%only%") )
UNION
(SELECT *, 3 as ob FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%three%" OR `joke` LIKE "%three%") )
UNION
(SELECT *, 4 as ob FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%doors%" OR `joke` LIKE "%doors%"))
ORDER BY `ob`, `ups` DESC,`downs` ASC LIMIT 0, 30
答案 1 :(得分:3)
我得到了解决方案:
SELECT *
FROM (
(SELECT 1 as SortRank, uid, title, state, zip, region,cantone FROM company WHERE city=".$city." AND region=".$region." AND cantone=".$cantone.")
UNION
(SELECT 2 as SortRank, uid, title, state, zip, region,cantone FROM company WHERE region=".$region." AND cantone=".$cantone.")
union all
(SELECT 3 as SortRank, uid, title, state, zip, region,cantone FROM company WHERE cantone=".$cantone.")
) As u
GROUP BY uid
ORDER BY SortRank,state=2, title ASC
LIMIT 0,10
在上面的查询中,我想要结果,例如。首先显示城市,地区和cantone的所有记录,然后如果城市不可用,则显示所有带有region和cantone的记录,然后显示所有带有cantone of city的记录。 因此,删除我使用GROUP BY子句的重复记录,它将根据查询组对所有记录进行排序,然后对所有状态为2的记录进行排序。
答案 2 :(得分:2)
查询的作用是分别对每个子查询进行排序并统一所有子查询。无法保证订购结果。
您需要做的是按顺序订购统一查询:
Select * from (
(SELECT *, 1 as `p` FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%only three doors%" OR `joke` LIKE "%only three doors%"))
UNION
(SELECT *, 2 as `p` FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%only%" OR `joke` LIKE "%only%"))
UNION
(SELECT *, 3 as `p` FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%three%" OR `joke` LIKE "%three%"))
UNION
(SELECT *, 4 as `p` FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%doors%" OR `joke` LIKE "%doors%"))
) ORDER BY `p` ASC, `ups` DESC,`downs` ASC
答案 3 :(得分:0)
您应该能够使用UNION ALL删除重复删除(以及完整的结果集排序)。使用它,结果集应该是查询中select语句的顺序。
答案 4 :(得分:0)
也许这与问题有点无关,但对于那些想要联合两个或多个查询的不同列:
由于无法使用一个 order by
语句,因为两个查询中的列不相同,您可以考虑添加“假”列以使两个查询中的列数相等,这是我在 HackerRank 上对 excerise 的回答类似于这里提出的问题
WITH sub AS
(
(SELECT CONCAT(Name , "(" , SUBSTRING(OCCUPATION,1,1) , ")") as first , Name , OCCUPATION , -1 as counts FROM OCCUPATIONS)
UNION ALL
(SELECT CONCAT("There are a total of " , COUNT(OCCUPATION) , " " , LOWER(OCCUPATION) , "s" , ".") as first , "z" as Name , OCCUPATION , COUNT(OCCUPATION) as counts FROM OCCUPATIONS
GROUP BY OCCUPATION)
)
SELECT first FROM sub
ORDER BY Name ASC , counts ASC , OCCUPATION ASC
注意:您应该为假列选择适当的值以使您的行处于正确位置(注意我的查询中的 -1 as counts FROM OCCUPATIONS
、"z" as Name
)
我最初误解了 HackerRank 上的问题,因为它不需要我将两个查询结合起来,但无论如何我最终还是学到了一些新东西,希望对您有所帮助 (: