我遇到一种情况,我需要根据具有优先顺序的一组设置标准从表中获取X条记录。换句话说:
一个具体示例:
+----+-----------------+-------------------+-------------+
| id | primary_user_id | secondary_user_id | location_id |
+----+-----------------+-------------------+-------------+
| 1 | user1 | user1 | MI |
| 2 | user1 | user2 | NV |
| 3 | user2 | user1 | MI |
| 4 | user1 | user3 | MI |
| 5 | user4 | user5 | NV |
+----+-----------------+-------------------+-------------+
secondary_user_id = @user
primary_user_id = @user
location_id = @location
根据我的理解,简单的OR子句不能保证返回的记录与获取记录的标准顺序相同:
SELECT * FROM Foo WHERE
secondary_user_id = 'user1' OR
primary_user_id = 'user1' OR
location_id = 'NV'
LIMIT 2
UNION似乎是一个更好的选择:
SELECT * FROM Foo WHERE secondary_user_id = 'user1'
UNION
SELECT * From Foo WHERE primary_user_id = 'user1'
UNION
SELECT * FROM Foo WHERE location_id = 'NV'
有限制:
SELECT * FROM (
SELECT * FROM Foo WHERE secondary_user_id = 'user1'
UNION
SELECT * From Foo WHERE primary_user_id = 'user1'
UNION
SELECT * FROM Foo WHERE location_id = 'NV'
) AS r LIMIT 2
如果要确保结果与获取标准时的顺序相同,UNION是这里的唯一选择吗?我知道可以在我的应用程序中以编程方式完成此操作,但是我想尽可能地将很多工作分担给数据库(如果重要的话,可以使用MySQL)。
答案 0 :(得分:0)
由于您希望将其保留在MySQL中,因此您的上一个查询看起来是该任务的最佳工作解决方案。
唯一的问题是UNION
子句可能会多次给您一些行。例如,如果某行包含secondary_user_id = 'user1'
和primary_user_id = 'user1'
,则它将返回两次。
为避免这种情况,请使用DISTINCT
:
SELECT DISTINCT * FROM (
SELECT * FROM Foo WHERE secondary_user_id = 'user1'
UNION
SELECT * From Foo WHERE primary_user_id = 'user1'
UNION
SELECT * FROM Foo WHERE location_id = 'NV'
) AS r LIMIT 2
已编辑
@ZaynulAbadinTuhin完全正确
UNION
如果两个查询返回相同的名称,则会自动生成DISTINCT
因此,从该问题进行的最后一个查询无需任何更改即可正常工作。
答案 1 :(得分:0)
您还可以简单地使用OR,然后使用CASE添加ORDER BY:
SELECT *
FROM Foo
WHERE secondary_user_id = 'user1'
OR primary_user_id = 'user1'
OR location_id = 'NV'
ORDER BY (CASE
WHEN secondary_user_id = 'user1' THEN 0
ELSE 100
END) +
(CASE
WHEN primary_user_id = 'user1' THEN 0
ELSE 10
END) +
(CASE
WHEN location_id = 'NV' THEN 0
ELSE 1
END);
这是有效的,但可读性较差。
答案 2 :(得分:0)
只需使用order by
:
SELECT *
FROM Foo
WHERE secondary_user_id = 'user1' OR
primary_user_id = 'user1' OR
location_id = 'NV'
ORDER BY (CASE WHEN secondary_user_id = 'user1' THEN 1
WHEN primary_user_id = 'user1' THEN 2
ELSE 3
END)
LIMIT 2;
请勿重复,我重复请勿,并假设UNION
或UNION ALL
将按特定顺序产生结果。保证排序的唯一方法是使用显式的ORDER BY
子句。