问题
My friend asked a question a few times ago. Also there is a answer under that and it is good, but not for my case. The idea of that solution is joining the current table to itself. That seems expensive and not effective for me, Because in reality there is four join
on these tables (votes
, favorites
, comments
, viewed
) in my query.
Now I want to know, how can I do that using CASE
function? Something like this:
... ORDER BY Type, CASE WHEN AcceptedAnswerId = Id THEN 1 ELSE 0, timestamp
Or is there any better solution?
To be more readable, I paste those examples here:
I have a table like this:
// 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 |
+----+--------------------+------+------------------+-----------+
Now I want this result: (please focus on the order)
+----+--------------------+------+------------------+-----------+
| 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
回答1:
CASE would work, but you are missing the END
. But in this case, you could also just use IF(AcceptedAnswerId = Id,1,0)
.
In the simple case you show, you could just do:
order by type,if(type=0,(@accepted:=acceptedanswerid),id<>@accepted),timestamp
but I don't know if that would work in your real case.
回答2:
Given the table definition (without proper indices) + sample data
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)
you can use the query
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
to get the question/answer set of a specific question (t1.related = 1
<- adjust that parameter for other questions).
And no, with the right indices this query is not "expensive".
example at http://sqlfiddle.com/#!9/24954/4 (yeah, took me 4 attempts to get it right, grrrrr)
来源:https://stackoverflow.com/questions/34735047/how-to-use-case-function-in-order-by