Mysql query with multiple ORDER BY clause and IF conditions - mysql

I am trying to query based on these conditions in an orders table,
// This is not an actual query
SELECT *
IF (store_id = 3) THEN ORDER BY WEIGHT DESC,
ELSEIF (STORE_ID = 7) THEN ORDER BY WEIGHT DESC
ELSEIF ORDER BY WEIGHT = DESC
ELSEIF (EQUAL WEIGHT) ORDER BY ORDER_DATE DESC
ELSEIF (EQUAL WEIGHT AND EQUAL ORDER_DATE) ORDER BY STORE_ID DESC
ELSEIF (EQUAL WEIGHT AND EQUAL ORDER_DATE AND EQUAL STORE_ID) ORDER BY
SHIPPING_METHOD DESC
FROM TABLE orders WHERE carrier_name = 'XXX'
This is as far as what I have got,
//Actual query
SELECT id,store_id,weight
FROM orders
WHERE carrier_name = 'XXX'
ORDER BY
IF(store_id = 3,weight,'')DESC,
IF(store_id = 3,order_date,'')DESC,
IF(store_id = 3,store_id,'')DESC,
IF(store_id = 3,shipping_method,'')DESC,
IF(store_id = 7,weight,'')DESC,
IF(store_id = 7,order_date,'')DESC,
IF(store_id = 7,store_id,'')DESC,
IF(store_id = 7,shipping_method,'')DESC,
IF(TRUE,weight,'')DESC,
IF(TRUE,order_date,'')DESC,
IF(TRUE,store_id,'')DESC,
IF(TRUE,shipping_method,'')DESC
The result obtained is
I am not sure why 53.39 and 30.35 are not sorted. What am I doing wrong?
Please suggest if there is a better way to attain this.
This is the required result,

Based on your expected output, the following query should give you what you want:
SELECT *
FROM orders
WHERE carrier_name = 'XXX'
ORDER BY CASE WHEN store_id = 3 THEN 0
WHEN store_id = 7 THEN 1
ELSE 2 END,
store_id,
weight DESC
For an explanation of the logic in the ORDER BY clause, the first condition puts store_id 3 first, followed by 7, followed by everything else. The next conditions orders each of these three groups in ascending order by the store_id. Note that for 3 and 7, this second step will be ignored, because the store_id value is the same for these groups (3 and 7 respectively). Finally, the third condition is to order by the weight in descending order.

ORDER BY
weight DESC, -- as i can see all true in your cases
order_date DESC,
store_id DESC,
shipping_method DESC

Related

Mysql filter SELECT query result.

I have the following query.
SELECT COUNT(id) AS NumResults, race_date AS RaceDate, race_time AS RaceTime
FROM results
WHere jockeys_claim = 10
GROUP BY race_date DESC, race_time ASC
I would then like to filter out the NumResults , so the table only shows results where the NumResults = 1. Thanks for looking.
Use the HAVING clause to filter the results of an aggregate function (the COUNT in your case)
SELECT COUNT(id) AS NumResults, race_date AS RaceDate, race_time AS RaceTime
FROM results
WHere jockeys_claim = 10
GROUP BY race_date, race_time
HAVING COUNT(id) = 1
ORDER BY race_date DESC, race_time ASC

MySQL clause in where `case when`

I am trying to figure it out but no solution at all.
My query :
SELECT * FROM table
WHERE owner = 'user'
AND (
CASE WHEN status = 'NEW'
THEN status = 'NEW'
ELSE status IN ('CB','NA','NI','GC','FC')
END
)
ORDER BY RAND() DESC
LIMIT 1;
What I want to achieve is to show all records where status is NEW in an Random order limited by one row each, when no records NEW for the user the query needs to show the other statuses.
Thank you.
SELECT * FROM Table
WHERE owner = 'user'
AND (CASE WHEN (SELECT COUNT(*) FROM Table WHERE status = 'NEW') >= 1 THEN
status = 'NEW'
ELSE status IN ('CB','NA','NI','GC','FC')
END)
ORDER BY RAND() DESC
LIMIT 1;
Demo
http://sqlfiddle.com/#!9/09b1c8/1
What i think, you can simply
SELECT * FROM table
WHERE owner = 'user'
AND (
CASE WHEN status = 'NEW'
THEN status = 'NEW'
ELSE status IN ('CB','NA','NI','GC','FC')
END
)
ORDER BY RAND() DESC
LIMIT 1;
To
SELECT * FROM table
WHERE owner = 'user' AND status IN ('NEW','CB','NA','NI','GC','FC')
GROUP By some_id
ORDER BY RAND() DESC
LIMIT 1;
SELECT * FROM table
WHERE owner = 'user'
AND status IN ('NEW', 'CB','NA','NI','GC','FC')
ORDER BY status = 'NEW' DESC,
RAND() DESC
LIMIT 1;
Will give you a total of 1 row, giving preference to a random 'NEW'. If no 'NEW' rows, then a random one of the others.
(Please clarify your Question and provide sample output.)

How to get Last and Secondlast Record from mysql table

From the above image i have n number of records with cat_id and sub_cat_id but in image only two are there.
so i want get the last and secondlast score_in_per value as named lastScore and latetsScore..
how can i retrieve that..?
SELECT
(SELECT score_in_per FROM tbl_student_skill_score ORDER BY date DESC LIMIT 2,0) as lastScore,
(SELECT score_in_per FROM tbl_student_skill_score ORDER BY date DESC LIMIT 1) as latetsScore
i am new to this complicated mysql logics..This what i have tried..
Example:
lets say one user email is inststudent#yopmail.com take the same test 2 times and the test is linked up with one category and sub category.
so the user will take the test any number of times...
from that records i want to get the last two records percentage.
If I understand you correctly; you want to select the two most recent results of a specific type of test taken by a specific student.
You don't use the LIMIT clause correctly. This is the correct syntax: LIMIT {[offset,] row_count | row_count OFFSET offset}. Also, you completely left out the where clause.
So the query should be:
SELECT
(SELECT score_in_per FROM tbl_student_skill_score
WHERE user_email = "email of the user you are interested in"
AND cat_id = categoryOfTestOfInterest
AND sub_cat_id = subcategoryOfTestOfInterest
ORDER BY date DESC LIMIT 1, 1
)AS lastScore,
(SELECT score_in_per FROM tbl_student_skill_score
WHERE user_email = "email of the user you are interested in"
AND cat_id = categoryOfTestOfInterest
AND sub_cat_id = subcategoryOfTestOfInterest
ORDER BY date DESC LIMIT 1
)AS latetsScore;
If a student can take the test multiple times a day (like your image suggests) than you should also order by id (supposing that the id is always greater for newer results) or better still, only by the id:
SELECT
(SELECT score_in_per FROM tbl_student_skill_score
WHERE user_email = "email of the user you are interested in"
AND cat_id = categoryOfTestOfInterest
AND sub_cat_id = subcategoryOfTestOfInterest
ORDER BY id DESC LIMIT 1, 1
)AS lastScore,
(SELECT score_in_per FROM tbl_student_skill_score
WHERE user_email = "email of the user you are interested in"
AND cat_id = categoryOfTestOfInterest
AND sub_cat_id = subcategoryOfTestOfInterest
ORDER BY id DESC LIMIT 1
)AS latetsScore;
One of the way of solving this problem is by using Partition By .
Step1: I have ranked the data for distinct cat_id and sub_cat_id in descending order of date by partition by.
Step2: I have used rank1 which is the latest score and merged it with rank2 which is the second last score
with chck as
(select
cat_id,sub_cat_id,score_in_per,date1,
row_number() over(partition by cat_id,sub_cat_id order by
cat_id,sub_cat_id,date1 desc) as row_num
from tbl)
select a.*,b.second_last_score from
(select cat_id,sub_cat_id,score_in_per,date1,row_num as last_score from chck where row_num=1) a
left join
(select cat_id,sub_cat_id,score_in_per,date1,row_num as second_last_score from chck where row_num=2) b
on a.cat_id = b.cat_id and a.sub_cat_id = b.sub_cat_id;
Let me know in case of any query.
SELECT
( SELECT score_in_per FROM tbl_student_skill_score WHERE cat_id=1 and sub_cat_id=5 ORDER BY date,id DESC LIMIT 1 ) AS latestScore,
( SELECT score_in_per FROM tbl_student_skill_score WHERE cat_id=1 and sub_cat_id=5 ORDER BY date,id DESC LIMIT 1,1 ) AS lastScore

SQL Multi Order by Count with Criteria

I want to query standings from MotoGP Race result
my sql is
SELECT `Rider`, `Team`, `Bike`,SUM(`Points`)
FROM `table_name`
WHERE `Year` = 2015 AND `Classes` = "MotoGP"
GROUP BY `Year`,`Rider`
HAVING SUM(`Points`)
ORDER BY SUM(`Points`) DESC
If 2 or more riders have same SUM('Points'), the next order is by number of 1st race position.
I put the race position on 'Pos' field.
Pos value: 1,2,3,4,5 ...
Please help for the 2nd order. Thank you
You just need to change the HAVING clause:
ORDER BY SUM(`Points`) DESC,
SUM(RacePosition = 1) DESC
For multiple positions, I think you need to add the condition for each one:
ORDER BY SUM(`Points`) DESC,
SUM(RacePosition = 1) DESC,
SUM(RacePosition = 2) DESC,
SUM(RacePosition = 3) DESC
At some point, perhaps SUM(RacePosition) would do what you want.

ORDER BY is not working properly in MySQL

The following is my SELECT query I want with ORDER BY with transType = 'I' and after that with transdate in ascending order. Through that query i can get transType = 'I' record properly but after that it does not displays in proper sequence.
SELECT tranjectionId,date_format(transDate,'%d-%m-%Y') AS transDate,motiAmount,
transType,tranjection.partyId,item.itemName,gwt,loss,netwet,
party.partyName,melting,westage,finewet,rhodium,amount,bhav
FROM tranjection,party,item
WHERE party.partyId = tranjection.partyId
AND item.itemId = tranjection.itemId
AND tranjection.partyId = ".$partyId."
ORDER BY (transType = 'R') DESC,
transDate
While doing the order you may do as
order by
case
when transtype = 'I' then 0 else 1
end,
transdate;