如何在ORDER BY中使用CASE函数?
How to use CASE function in ORDER BY?
我的朋友问了几次。在那之下也有一个答案,这很好,但不适合我的情况。该解决方案的想法是将当前 table 加入自身。这对我来说似乎很昂贵而且无效,因为实际上这些 table 上有四个 join
(votes
、favorites
、comments
、viewed
) 在我的查询中。
现在我想知道,如何使用 CASE
函数来做到这一点?像这样:
... ORDER BY Type, CASE WHEN AcceptedAnswerId = Id THEN 1 ELSE 0, timestamp
或者有什么更好的解决办法吗?
为了提高可读性,我将这些示例粘贴到此处:
我有一个 table 这样的:
// Mytable
+----+--------------------+------+------------------+-----------+
| Id | QuestionOrAnswer | Type | AcceptedAnswerId | timestamp |
+----+--------------------+------+------------------+-----------+
| 1 | question1 | 0 | 3 | 1 |
| 2 | answer1 | 1 | NULL | 2 |
| 3 | answer2 | 1 | NULL | 3 | -- accepted answer
| 4 | answer3 | 1 | NULL | 4 |
+----+--------------------+------+------------------+-----------+
现在我想要这样的结果:(请注意顺序)
+----+--------------------+------+------------------+-----------+
| Id | QuestionOrAnswer | Type | AcceptedAnswerId | timestamp |
+----+--------------------+------+------------------+-----------+
| 1 | question1 | 0 | 3 | 1 |
| 3 | answer2 | 1 | NULL | 3 | -- accepted answer
| 2 | answer1 | 1 | NULL | 2 |
| 4 | answer3 | 1 | NULL | 4 |
+----+--------------------+------+------------------+-----------+
// ^ 0 means question and 1 means answer
CASE 可以,但您缺少 END
。但在这种情况下,您也可以只使用 IF(AcceptedAnswerId = Id,1,0)
.
在您展示的简单案例中,您可以只做:
order by type,if(type=0,(@accepted:=acceptedanswerid),id<>@accepted),timestamp
但我不知道这是否适用于您的实际情况。
给定 table 定义(没有适当的索引)+ 样本数据
CREATE TABLE Table1
(`Id` int, `QuestionOrAnswer` varchar(9), `Type` int, `AcceptedAnswerId` varchar(4), `related` int NOT NULL, `timestamp` int)
;
INSERT INTO Table1
(`Id`, `QuestionOrAnswer`, `Type`, `AcceptedAnswerId`, `related`, `timestamp`)
VALUES
(1, 'question1', 0, '3', 1, 1),
(2, 'answer1', 1, NULL, 1, 2),
(3, 'answer2', 1, NULL, 1, 3),
(4, 'answer3', 1, NULL, 1, 4)
您可以使用查询
SELECT
t2.*
FROM
table1 as t1
JOIN
table1 as t2
ON
t1.related=t2.related
WHERE
t1.related = 1
AND t1.Type = 0
ORDER BY
t2.Type desc, t2.Id=t1.AcceptedAnswerId, t2.Id
获取特定问题的 question/answer 组(t1.related = 1
<- 为其他问题调整该参数)。
不,使用正确的索引,此查询不是 "expensive".
示例 http://sqlfiddle.com/#!9/24954/4(是的,我尝试了 4 次才弄对,grrrrr)
我的朋友问了几次join
(votes
、favorites
、comments
、viewed
) 在我的查询中。
现在我想知道,如何使用 CASE
函数来做到这一点?像这样:
... ORDER BY Type, CASE WHEN AcceptedAnswerId = Id THEN 1 ELSE 0, timestamp
或者有什么更好的解决办法吗?
为了提高可读性,我将这些示例粘贴到此处:
我有一个 table 这样的:
// Mytable
+----+--------------------+------+------------------+-----------+
| Id | QuestionOrAnswer | Type | AcceptedAnswerId | timestamp |
+----+--------------------+------+------------------+-----------+
| 1 | question1 | 0 | 3 | 1 |
| 2 | answer1 | 1 | NULL | 2 |
| 3 | answer2 | 1 | NULL | 3 | -- accepted answer
| 4 | answer3 | 1 | NULL | 4 |
+----+--------------------+------+------------------+-----------+
现在我想要这样的结果:(请注意顺序)
+----+--------------------+------+------------------+-----------+
| Id | QuestionOrAnswer | Type | AcceptedAnswerId | timestamp |
+----+--------------------+------+------------------+-----------+
| 1 | question1 | 0 | 3 | 1 |
| 3 | answer2 | 1 | NULL | 3 | -- accepted answer
| 2 | answer1 | 1 | NULL | 2 |
| 4 | answer3 | 1 | NULL | 4 |
+----+--------------------+------+------------------+-----------+
// ^ 0 means question and 1 means answer
CASE 可以,但您缺少 END
。但在这种情况下,您也可以只使用 IF(AcceptedAnswerId = Id,1,0)
.
在您展示的简单案例中,您可以只做:
order by type,if(type=0,(@accepted:=acceptedanswerid),id<>@accepted),timestamp
但我不知道这是否适用于您的实际情况。
给定 table 定义(没有适当的索引)+ 样本数据
CREATE TABLE Table1
(`Id` int, `QuestionOrAnswer` varchar(9), `Type` int, `AcceptedAnswerId` varchar(4), `related` int NOT NULL, `timestamp` int)
;
INSERT INTO Table1
(`Id`, `QuestionOrAnswer`, `Type`, `AcceptedAnswerId`, `related`, `timestamp`)
VALUES
(1, 'question1', 0, '3', 1, 1),
(2, 'answer1', 1, NULL, 1, 2),
(3, 'answer2', 1, NULL, 1, 3),
(4, 'answer3', 1, NULL, 1, 4)
您可以使用查询
SELECT
t2.*
FROM
table1 as t1
JOIN
table1 as t2
ON
t1.related=t2.related
WHERE
t1.related = 1
AND t1.Type = 0
ORDER BY
t2.Type desc, t2.Id=t1.AcceptedAnswerId, t2.Id
获取特定问题的 question/answer 组(t1.related = 1
<- 为其他问题调整该参数)。
不,使用正确的索引,此查询不是 "expensive".
示例 http://sqlfiddle.com/#!9/24954/4(是的,我尝试了 4 次才弄对,grrrrr)