【发布时间】:2015-05-20 06:15:39
【问题描述】:
我要返回两种类型的结果:
- 未读通知
- 阅读通知
如果有超过 10 个未读通知可用,我想选择尽可能多的通知
如果有
如果我只想选择所有未读通知,我的查询将是:
SELECT * FROM notifications WHERE read = 0
如果我只想选择所有已读通知,我的查询将是:
SELECT * FROM notifications WHERE read = 1
【问题讨论】:
我要返回两种类型的结果:
如果有超过 10 个未读通知可用,我想选择尽可能多的通知
如果有
如果我只想选择所有未读通知,我的查询将是:
SELECT * FROM notifications WHERE read = 0
如果我只想选择所有已读通知,我的查询将是:
SELECT * FROM notifications WHERE read = 1
【问题讨论】:
这应该对你有帮助: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
【讨论】:
row_number()。在 SQL Server 和 Postgresql 中以不同方式完成 stackoverflow.com/questions/3959692/rownum-in-postgresql
你可以做的是将两个结果联合起来,按最重要的顺序排列,然后限制联合:
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;
编辑,回复:必须返回 ALL Unread,而不仅仅是前 10 个
抱歉,我错过了问题的那一部分。我想不出一种优雅的方式来实现这一点,所以 这里有一个~部分解决方案,如果需要,它会使用命令式过程和一个临时表来填充行: 在 MySql 之前使用codingbiz 的解决方案支持窗口函数(例如ROW_NUMBER() OVER (PARTITION BY read ORDER BY Col1 DESC)
【讨论】:
如果表没有变大,您可以尝试如下加入它们
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 人),但也许它可以帮助你。
【讨论】:
ROW_NUMBER()
请检查此解决方案。
SELECT * FROM `notifications` WHERE `read`=1 OR `read`=0 ORDER BY `read` LIMIT 10
【讨论】: