Order by With Union SQL - mysql

SELECT to_user_id AS sender_id
FROM $chat_table_name
WHERE((to_user_id = $current_user_id OR from_user_id = $current_user_id) and post_id=$post_id)
UNION
SELECT from_user_id AS receiver_id
FROM $chat_table_name
WHERE( (from_user_id = $current_user_id OR to_user_id = $current_user_id) and post_id=$post_id )
order by chat_message_id DESC
How to achieve order by with this query

If I get your question correct, you want to order the indivual SELECTs seperately and you cannot use two ORDER BY clause per each statement instead, add an extra integer column to each SELECT as shown below:
SELECT *, 1 as orderBy from t1
UNION ALL
SELECT *, 2 as orderBy from t2
ORDER BY orderBy desc.

Related

Get latest two distinct location from table

Below is my table,
SELECT DISTINCT(availability_location) as location FROM table_name WHERE user_id = '8' ORDER BY availability_date DESC LIMIT 2
I'm getting following result
I want following result :
2016-05-27 pune
2016-05-20 Burbank
i.e. Unique availability_location as well as latest two entries.
You have to use GROUP BY for this:
SELECT availability_location as location,
MAX(availability_date) AS max_date
FROM table_name
WHERE user_id = '8'
GROUP BY location
ORDER BY max_date DESC LIMIT 2
You can use GROUP BY and order by the max date :
SELECT t.availability_location
FROM table_name t
WHERE user_id = '8'
GROUP BY t.availability_location
ORDER BY max(s.availability_date) DESC LIMIT 2
Output :
availability_location
---------------------
pune
Burbank
EDIT: next time, you should mention that you want it to be case sensitive. You can try doing it like this:
SELECT t.availability_location
FROM table_name t
INNER JOIN(SELECT s.availability_location , max(s.availability_date) as max_d
FROM table_name s
WHERE s.user_id = '8'
GROUP BY s.availability_location) t2
ON(t2.availability_location = t.availability_location AND
t2.max_d = t.availability_date)
ORDER BY t.availability_date DESC LIMIT 2

Order mysql query in the same order I provide the OR statements in

Here's a query:
SELECT *
FROM table
WHERE id = 1
OR id = 100
OR id = 50
Note that I provided the ids in this order: 1,100,50.
I want the rows to come back in that order: 1,100,50.
Currently, i comes back 1,50,100 - basically in ascending order. Assume the rows in the table were inserted in ascending order also.
Use the MySQL specific FIND_IN_SET function:
SELECT t.*
FROM table t
WHERE t.id IN (1, 100, 50)
ORDER BY FIND_IN_SET(CAST(t.id AS VARCHAR(8)), '1,100,50')
Another way to approach this would put the list in a subquery:
select table.*
from table join
(select 1 as id, 1 as ordering union all
select 100 as id, 2 as ordering union all
select 50 as id, 3 as ordering
) list
on table.id = list.id
order by list.ordering
You can just do this with ORDER BY:
ORDER BY
id = 1 DESC, id = 100 DESC, id = 50 DESC
0 is before 1 in ORDER BY.
Try this
SELECT *
FROM new
WHERE ID =1
OR ID =100
OR ID =50
ORDER BY ID=1 DESC,ID=100 DESC,ID=50 DESC ;
http://www.sqlfiddle.com/#!2/796e2/5
... WHERE id IN (x,y,x) ORDER BY FIELD (id,x,y,z)

How to select more rows from subquery

When I'm trying to run this query:
select * FROM `activity`
WHERE user_id = 1
AND activity_id NOT LIKE (select activity_id from activity where user_id = 1 ORDER BY activity_id DESC LIMIT 8)
I get the follow error:
Subquery returns more than 1 row
How can I solve this problem? I want to select the activity_id from the table excluding the latest 8 activity_id's for a certain user.
NOT LIKE is expecting an expression or a value to compare against and not a resultset.
Change NOT LIKE for NOT IN
Try this one:
SELECT * FROM `activity`
WHERE user_id = 1 AND activity_id NOT IN (
SELECT activity_id FROM activity WHERE user_id = 1
ORDER BY activity_id DESC LIMIT 8)
Solved it by doing this:
$sql2 = "DELETE t1.*
FROM activity t1
left join (select activity_id from activity where user_id = '".$row['user_id']."' ORDER BY activity_id DESC LIMIT 8) t2
on (t1.activity_id = t2.activity_id)
where t2.activity_id is null
and t1.user_id = '".$row['user_id']."'";

Weird result with UNION and ORDER BY

I have this query (simplified):
SELECT score FROM tbl WHERE id = xx ORDER BY score DESC;
And it works correctly. Now I add to this query an UNION like this:
(SELECT score FROM tbl WHERE id = x ORDER BY score DESC)
UNION
(SELECT score FROM tbl WHERE id = y)
Now all the first result-set of the first query is messed up not respecting the ORDER BY score DESC
SELECT score FROM tbl WHERE id = x
UNION
SELECT score FROM tbl WHERE id = y
ORDER BY score DESC;
just add the order by to the end. it will apply to the entire result set. If you want to differentiate the result add an order col like so:
SELECT 1 as order_col, score FROM tbl WHERE id = x
UNION
SELECT 2 as order_col, score FROM tbl WHERE id = y
ORDER BY order_col ,score DESC;
In a union query, the order by must be put with the last select.
Ok I found the solution.
UNION and ORDER BY isn't allowed. I can only put ORDER BY at the end of UNION

Select the 3 most recent records where the values of one column are distinct

I have the following table:
id time text otheridentifier
-------------------------------------------
1 6 apple 4
2 7 orange 4
3 8 banana 3
4 9 pear 3
5 10 grape 2
What I want to do is select the 3 most recent records (by time desc), whose otheridentifiers are distinct. So in this case, the result would be id's: 5, 4, and 2.
id = 3 would be skipped because there's a more recent record with the same otheridentifier field.
Here's what I tried to do:
SELECT * FROM `table` GROUP BY (`otheridentifier`) ORDER BY `time` DESC LIMIT 3
However, I end up getting rows of id = 5, 3, and 1 instead of 5, 4, 2 as expected.
Can someone tell me why this query wouldn't return what I expected? I tried changing the ORDER BY to ASC but this simply rearranges the returned rows to 1, 3, 5.
It doesn't return what you expect because grouping happens before ordering, as reflected by the position of the clauses in the SQL statement. You're unfortunately going to have to get fancier to get the rows you want. Try this:
SELECT *
FROM `table`
WHERE `id` = (
SELECT `id`
FROM `table` as `alt`
WHERE `alt`.`otheridentifier` = `table`.`otheridentifier`
ORDER BY `time` DESC
LIMIT 1
)
ORDER BY `time` DESC
LIMIT 3
You could join the table on itself to filter the last entry per otheridentifier, and then take the top 3 rows of that:
SELECT last.*
FROM `table` last
LEFT JOIN `table` prev
ON prev.`otheridentifier` = last.`otheridentifier`
AND prev.`time` < last.`time`
WHERE prev.`id` is null
ORDER BY last.`time` DESC
LIMIT 3
I had a similar requirement, but I had more advanced selection criteria. Using some of the other answers I couldn't get exactly what I needed, but I found you can still do a GROUP BY after and ORDER BY like this:
SELECT t.* FROM (SELECT * FROM table ORDER BY time DESC) t
GROUP BY t.otheridentifier
SELECT * FROM table t1
WHERE t1.time =
(SELECT MAX(time) FROM table t2
WHERE t2.otheridentifier = t1.otheridentifier)
Andomar's answer is probably best in that it doesn't use a subquery.
An alternative approach:
select *
from `table` t1
where t1.`time` in (
select max(s2.`time`)
from `table` t2
group by t2.otheridentifier
)
You can use this query to get correct answer:
SELECT * FROM
(SELECT * FROM `table` order by time DESC)
t group by otheridentifier
what about
SELECT *, max(time) FROM `table` group by otheridentifier
This also:
SELECT * FROM
OrigTable T INNER JOIN
(
SELECT otheridentifier,max(time) AS duration
FROM T
GROUP BY otheridentifier) S
ON S.duration = T.time AND S.otheridentifier = T.otheridentifier.