How to use CASE function in ORDER BY?

柔情痞子 提交于 2019-11-30 09:41:47

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!