我想要返回两种类型的结果:
如果有> 10个未读通知我想选择多少个
如果有< = 10,我想选择所有(比如有7个)未读通知和3'填充'读取通知。我怎么能做到这一点?
如果我只想选择所有未读通知,我的查询将是:
SELECT * FROM notifications WHERE read = 0
如果我只想选择所有阅读通知,我的查询将是:
SELECT * FROM notifications WHERE read = 1
答案 0 :(得分:5)
你可以做的是将两个结果合并,按最重要的顺序排列,然后限制联盟:
SELECT Col1, Col2, ...
FROM
(
SELECT Col1, Col2, `read`, ... FROM notifications WHERE read = 0
UNION
SELECT Col1, Col2, `read`, ... FROM notifications WHERE read = 1
) x
ORDER BY x.`read` -- And probably a column like Time?
LIMIT 10;
编辑,重新:必须返回所有未读,而不仅仅是前10
道歉,我错过了这个问题的一部分。我无法想到一种优雅的方法来实现这一目标,所以ROW_NUMBER() OVER (PARTITION BY read ORDER BY Col1 DESC)
)
答案 1 :(得分:5)
这可以帮助您:http://sqlfiddle.com/#!9/e7e2a/2
SELECT * FROM
(
SELECT @rownum := @rownum + 1 AS rownum, name, read
FROM notifications,
(SELECT @rownum := 0) r --initialise @rownum to 0
) t
WHERE read = 0 OR (read = 1 AND rownum <= 10)
ORDER BY rownum
记录用@rownum编号。 where子句确保首先选择read = 0。如果它们最多10个或更多,则全部被选中。但如果没有,则检查第二个标准(read = 1 AND rownum <= 10)
。
(SELECT @rownum := 0) r
将@rownum
初始化为0,否则将NULL
和NULL+1=NULL
答案 2 :(得分:0)
如果表格没有变大,您可以尝试加入它们,如下所示
SELECT *,
ROW_NUMBER() OVER (
ORDER BY read
) AS RowNum
FROM (
SELECT * FROM notifications WHERE read = 0
UNION
SELECT * FROM notifications WHERE read = 1
) T1
WHERE T1.read = 0 OR (T1.read = 1 AND T1.RowNum <= 10)
ORDER BY T1.read DESC
当这些表格变得很大时,您可以尝试首先在“读取”表上运行计数,看看它是否有超过10条未读消息,并根据该结果选择读取或未读消息
INT @readMessages = SELECT COUNT(*) FROM notifications WHERE read = 0
SELECT CASE
WHEN @readMessages > 10 THEN SELECT * FROM notifications WHERE read = 0
ELSE (
SELECT * FROM notifications WHERE read = 0
UNION
SELECT * FROM notifications WHERE read = 1 LIMIT 0, 10-@readMessages
)
不知道它是不是所有正确的MySQL语法(更像是一个SQL人员),但它可能对你有帮助。
答案 3 :(得分:-1)
请检查此解决方案。
SELECT * FROM `notifications` WHERE `read`=1 OR `read`=0 ORDER BY `read` LIMIT 10