Can anyone help me to write sql statement? - mysql

Can anyone help me to write sql below?
Suppose:
tbl_request
No Title Date Priority
1 AAA 2013-08-06 3
2 BBB 2013-08-04 1
3 CCC 2013-08-05 0
4 DDD 2013-08-02 4
5 EEE 2013-08-01 2
6 FFF 2013-08-04 0
7 GGG 2013-08-03 5
8 HHH 2013-08-03 0
There are two top priorities to order in sql statement:
1st priority: Ordering by Priority in Ascending (only 1,2,3,4,5)
2nd priority: Ordering by Date Descending
I want to show all request that order with the 1st priority first (0 won't display). After 1st priority, i want to display the 2nd priority.
Here is what i want:
No Title Date Priority
2 BBB 2013-08-04 1
5 EEE 2013-08-01 2
1 AAA 2013-08-06 3
4 DDD 2013-08-02 4
7 GGG 2013-08-03 5
3 FFF 2013-08-05 0
6 GGG 2013-08-04 0
8 HHH 2013-08-03 0
I don't know how to write sql statement to get the format above. Can anyone tell me how to write it?
Thank in advance.

How about something like
SELECT *
FROM Table1
ORDER BY
CASE WHEN `Priority` != 0 THEN NULL ELSE 1 END,
`Priority`,
`Date` DESC
or
SELECT *
FROM Table1
ORDER BY
CASE WHEN `Priority` != 0 THEN 0 ELSE 1 END,
`Priority`,
`Date` DESC
SQL Fiddle DEMO
This will ensure that even if any of the priorities are greater than the other answers max values, this will still sort 0 as last.

You could try something like:-
SELECT * FROM tbl_request
WHERE Priority IN (1, 2, 3, 4, 5)
ORDER BY Priority, DATE DESC
UNION
SELECT * FROM tbl_request
WHERE Priority NOT IN (1, 2, 3, 4, 5)
ORDER BY Date DESC;

select no,title,date,priority
from tbl_request
order by if(priority=0,99999,priority),date desc
This assumes that no priority is over 99999. Yo also need to pit back quotes around no and date columns - I don't have them on this keyboard!

You should use case expression as below
select No,Title,Date,Priority
from tab
order by
case
when Priority=0 then 9999
else Priority
end,
Date desc

If you aren't displaying 0 Priority records, then the below SQL statement will do just fine.
SELECT * FROM tbl_request WHERE Priority <> 0 ORDER BY Priority ASC, Date DESC

You can try:
Select title, date, priority from tbl_request Order By IF(priority = 0, 99999, priority) asc, date desc
though it is ugly, inefficient, it works for you. Or you can consider making a union of to sub queries
Select title, date, priority from tbl_request where priority > 0 order by priority asc
union
Select title, date, priority from tbl_request where priority = 0 order by date desc

SELECT *
FROM Table1
ORDER BY
(CASE WHEN Priority = 0 THEN 9999 ELSE 1 END) asc, date desc

SELECT *
FROM Table1
ORDER BY field(`Priority`,0),`Priority`,
`Date` DESC
FIDDLE

Select * from tbl_request
Order by ( CASE WHEN Priority > 0 THEN Priority ELSE 99999999 END ), DATE DESC

Related

MySQL: Order by specific items first then by time

Lets say we have a table
names
-------------------
id name created_at
1 alpha 2020-10-23 17:30:35
2 beta 2020-10-24 17:30:35
3 gamma 2020-10-25 17:30:35
4 kilo 2020-10-26 17:30:35
5 charlie 2020-10-27 17:30:35
6 hector 2020-10-28 17:30:35
I want to order the first few rows by a fixed array let's say 6,3,2 and the rest by created_at in desc order.
So the order that I'm expecting would be 6,3,2,5,4,1.
How can I achieve this using Mysql ?
I tried using field() but can't get it to work with the other column.
FIELD() is tricky for this, because it returns 0 if there are no matches. You can construct an expression that does what you want:
order by coalesce(nullif(field(id, 6, 3, 2), 0), 999999),
created_at desc
If you know that the ids are always descending for the fixed values, then you can use:
order by (case when id in (6, 3, 2) then id end) desc,
created_at desc
SELECT * FROM names ORDER BY (
CASE
WHEN id = 6 THEN 1
WHEN id = 3 THEN 2
WHEN id = 2 THEN 3
ELSE 4
END, created_at DESC
)
The CASE statement ensures the first 3 items listed are 6, 3 and 2, and the rest are listed in created_at DESC order.
One option would be to write a case expression as follows
select *
from names
order by case when id in (6,3,2) then 0
else 1
end asc,created_at desc

SQL oder by ASC over 0, then 0

I need an SQL query that's do an ORDER ASC > 0, then = 0 at the end to the query result.
SELECT * FROM TABLE WHERE rank>0 ORDER BY rank ASC
and then, put at the end the ones whose rank is 0
Name Rank
Martin 0
Bob 2
Marc 8
Mario 0
Sophia 4
After the query :
Name Rank
Bob 2
Marc 4
Sophia 8
Martin 0
Mario 0
Thanks !
Just do this:
ORDER BY rank=0 ASC, rank ASC
The expression rank=0 evaluates as a boolean expression, returns 0 for FALSE, 1 for TRUE, or NULL.
The more ANSI compliant equivalent syntax for rank=0 would be:
CASE WHEN rank = 0 THEN 1 WHEN rank IS NULL THEN NULL ELSE 0 END
Given the example data, this shows how the ordering by rank=0 achieves the result.
Name Rank rank=0
------- ---- ------
Bob 2 0
Sophia 4 0
Marc 8 0
Mario 0 1
Martin 0 1
(NOTE: the order of the rows withing equal values of rank is indeterminate; there's no guarantee of the order of Mario and Martin... either way is compliant with the ORDER BY specification.)
Try following
SELECT *, IF(rank>0,1,0) as Ordering FROM TABLE ORDER BY Ordering DESC, rank ASC
You can then change the ordering with Ordering DESC to bring the results with ZERO rank either at the beginning or end of the result set

SUM of rows in My Sql with condition

My Data is
ID SCORE
1 55
1 -1
1 25
1 -1
1 -1
1 35
2 25
2 -1
2 65
2 55
2 21
2 -1
Now i want to add/sum the score of each id ignoring -1 and i am trying with this code which is not working
SELECT SUM(CASE when SCORE>-1 THEN SUM(SCORE) ELSE 0 END)
FROM jbit WHERE htno='$id'
Here i am already using WHERE so how can i use another WHERE, if i use multiple Where in single query it may effect other processes.. please help me out
Help me out friends
if there is only two column then there is no need to use SUM, you can try below
SELECT id, IF(SCORE=-1,0,SCORE) AS scoreSum
FROM table1
GROUP BY id
Working DEMO
alternative ( not tested )
SELECT id, SUM(IF(SCORE=-1,0,SCORE)) AS scoreSum
FROM table1
WHERE htno =$id
GROUP BY id
SELECT SUM(score) AS score_sum
FROM jbit
WHERE htno='$id'
AND score <> -1 ;
SELECT SUM(`SCORE`)
FROM `jbit`
WHERE `htno` = '$id'
`SCORE` > 0;
Though, I'd suggest you to change '$id' to just $id if the column type of htno is INTEGER.
SELECT SUM(score) FROM <tablename> WHERE score != -1

Max and Min in the same table

Suppose I have the following table:
id flag date
1 1 2012-01-01
2 1 2012-02-01
3 1 2012-03-01
4 0 2012-04-01
5 0 2012-05-01
6 0 2012-06-01
Is there anyway I can get maximum date for rows with flag as 1 and minimum date for row with flag as 0 using the same query?
Edited:
I want the result to looks something like this:
max min
2012-03-01 2012-04-01
Thank you.
You can try something like
SELECT MAX(CASE WHEN FLAG = 1 THEN Date ELSE NULL END) MaxFlag1,
MIN(CASE WHEN FLAG = 0 THEN Date ELSE NULL END) MinFlag0
FROM [Table]
try
select flag,
case when flag = 1 then max([date])
when flag = 0 then min([date])
end as date
from your_table
group by flag
You can use a UNION (ALL) to combine the results of two statements. The only restriction on those statements is that they both return the same amount and same type of columns.
Applied to your example, this would become
SELECT MAX(date) FROM YourTable WHERE flag = 1
UNION ALL SELECT MIN(date) FROM YourTable WHERE flag = 0

SQL Query - order by date but also group

OK Ladies and Gents, I would really appreciate some help:
This is my table:
ID postID replyID content entry_date
1 0 40 hey 12/7
2 0 40 hi 12/8
3 0 40 whatsup 12/9
4 2 40 why? 12/10
5 0 40 who? 12/11
I need to run a query to get it like this:
ID postID replyID content entry_date
1 0 40 hey 12/7
2 0 40 hi 12/8
4 2 40 why? 12/10
3 0 40 whatsup 12/9
5 0 40 who? 12/11
You will see that ID 3 and 4 have switched. So basically I need to ASC by entry_date, unless ID = POSTID, then I need those two grouped together and also ASC by entry_date for those two.
Here is what I have tried but I am totally lost:
SELECT t1.ID, t1.postID, t1.replyID, t1.content, t1.entry_date
FROM discussion t1, discussion t2
WHERE t1.replyID = '40' AND t1.ID = t2.postID
ORDER BY t1.entry_date ASC
Which basically does nothing but finds where a row of ID = a row of postID
You can add a CASE statement to your ORDER BY clause
ORDER BY
CASE WHEN postID = 0 THEN ID ELSE postID END
, entry_date
doing so, you can discard the join alltogether and the entire statement could be simplified to
SELECT ID
, postID
, replyID
, content
, entry_date
FROM discussion
ORDER BY
CASE WHEN postID = 0 THEN ID ELSE postID END
, entry_date
Note that I do assume the entry date being a DATETIME column, not a VARCHAR column.