mysql query ORDER BY supplied condition - php

SELECT * FROM newmessage
ORDER BY id <somecondition>
here my condition is like :
(5, 3, 2, 1, 4)
ie. i want to ORDER the result according to id like my given order above.

SELECT * FROM newmessage
WHERE id IN (5, 3, 2, 1, 4)
ORDER BY FIELD(id, 5, 3, 2, 1, 4)
UNION
SELECT * FROM newmessage WHERE id NOT IN (5, 3, 2, 1, 4)

You need to use a CASE statement in the ORDER BY clause. It's a bit awkward, but does the job:
SELECT * FROM newmessage m
ORDER BY CASE WHEN m.someColumn = 5 THEN 1
WHEN m.someColumn = 3 THEN 2
WHEN m.someColumn = 2 THEN 3
WHEN m.someColumn = 1 THEN 4
WHEN m.someColumn = 4 THEN 5
ELSE m.someColumn END
EDIT : I would add, mind you, that if you have do the ability to add an 'index' or 'sort' column to the NewMessage table, then you should. Whilst my CASE hack works, it's not pretty.

One way of doing this is the fallowing:
SELECT * FROM table ORDER BY id IN(7, 13, 12) DESC;
which will sort the rows with id 7, 12 and 13 first, it will not sort in the exact order that you list in the IN() statement.
Here's how you can sort in a specific order:
SELECT * FROM table ORDER BY id = 7 DESC, id = 13 DESC, id = 12 DESC;
which will give the rows in the order that you list them. Of course, the ASC/DESC part still applies here, I just assume you need this ids first. It's a little cumbersome, but I don't think there's a more elegant way to achieve this.

It sounds like you might want to look at ORDER BY FIELD.
It allows you to specify a custom order for a given field, so you might use like this:
SELECT someField,priority FROM myTable
ORDER BY FIELD (priority,'HIGH','MEDIUM','LOW')
Which would give you priorities in that order, rather than alphabetical as would normally happen there.
So an example for the query you supplied might be:
ORDER BY FIELD(id,'5','3','2','1','4')

You can sort like this in MySQL using FIELD:
SELECT *
FROM newmessage
ORDER BY FIELD(id, 5, 3, 2, 1, 4)
however:
this will probably not work as expected, when there are more rows in the table, then those specified in the ORDER clause. So you would either have to put all IDs in there or add a filter, if you want to only return these 5 rows.

Related

SELECT * FROM table WHERE (my_id) IN table_column (assigned_id)

I have a table called tasks Where has a column named assigned_id which has comma separated values like (1, 2, 3, 4, 5). I need to count of the tasks user has assigned.
In Example: My name is Imdad and my user_id is 5, and the tasks table has column assigned_id which values are like 1, 3, 4, 5, 7... I need to count all the number of rows which assigned_id contain my user_id which is 5.
I have tried so many methods but not working till now.
I have tried
SELECT * FROM tasks WHERE $user_id IN (assigned_id);
Here the user_id is 5
It's returning if the assign_id value start with 5 (Example: 5, 3, 6, 7...)
Here is my code
<?php
$data = "SELECT COUNT('1') FROM task WHERE $user[id] IN (assigned_id)";
$get_data = mysqli_query($conn, $data);
$show = mysqli_fetch_array($get_data);
echo $show[0];
?>
I am attaching a screenshot for better understand!!!
Here I have marked the data which I want
But Here is the image with query, I got the first value
As per my understanding on the above query this should work for you in MYSQL
if you want to get based on task_title
Select count(*) from tasks where assignee_id LIKE (CONCAT('%', (Select id from tasks where task_title = 'Imdad' LIMIT 1), '%'));
if you want to get based on id
Select count(*) from tasks where assignee_id LIKE (CONCAT('%', (Select id from tasks where id = 5 LIMIT 1), '%'));
Hope this helps.
In such case you can use find_in_set function like:
select *
from tbl
where find_in_set(5, assigned_id);
SQL online editor

Retrieving data from SQL table

I have a table in which all action logs are stored. It contains "user_id" (to mark user), "statement_id" (to mark statement that has been worked on), "action_date" (to mark action time) and "action_type" (to mark what action was done). A user can work on many statements on which many actions can be performed.
I need to produce a query that will show what statements were worked on at a specific time (let's say from March 1, 2018 to March 30, 2018) - that I can do. The difficulty for me is to limit the outcome. I mean precisely how to limit the outcome from this:
Statements that were worked on: 30, 30, 30, 18, 18, 42, 42, 42
To this:
Statements that were worked on: 30, 18, 42
I tried to work with queries like this one but I'm no professional. I find it difficult to understand the concept of some limiting SQL commands.
SELECT * FROM action_log
WHERE user_id = 1
AND action_date >= 1519858800
AND action_date <= 1522447200
GROUP BY user_id
HAVING user_id = 1
ORDER BY id DESC
I would be very grateful for any help.
I think you are looking for SELECT DISTINCT:
SELECT DISTINCT statement_id
FROM action_log al
WHERE user_id = 1 AND
action_date >= 1519858800 AND action_date <= 1522447200
ORDER BY statement_id DESC;
You might find this easier to maintain by using UNIX_TIMESTAMP():
SELECT DISTINCT statement_id
FROM action_log al
WHERE user_id = 1 AND
action_date >= UNIX_TIMESTAMP('2018-03-01') AND
action_date <= UNIX_TIMESTAMP('2018-03-30')
ORDER BY statement_id DESC;
I guess you only need unique values.
In SQL there is a special statement for this.
Use SELECT DISTINCT
SELECT DISTINCT * FROM action_log WHERE user_id = 1 AND action_date >= 1519858800 AND action_date <= 1522447200 GROUP BY user_id HAVING user_id = 1 ORDER BY id DESC;
You can use between for comparing action_date. And you can eliminate having condition because that is already used in where. WHERE user_id = 1 and HAVING user_id = 1 will result you the same. Hope following code will work for you.
SELECT * FROM action_log WHERE user_id = 1 AND action_date between '1519858800' AND '1522447200' GROUP BY statement_id ORDER BY id DESC

find entries to the left and right of a certain entry in a mysql table in a single query

Let's say I have a table in a database like this table. Let's say that I want to get the entries on the left and right of the entry whose the primary key is equal to 5 (or any other primary key). So in our case, I want to get the entries whose primary key is equal to 4 and 6 respectively. What is the SQL query that will give me such result? Can you guys translate the SQL query into a find('all') CakePHP query?
Thank you
NOTE: The ids are not necessarily contiguous, meaning, they do not necessarily follow the 1, 2, 3, 4, 5, 6, 7, 8 sequence. I can have something like 1, 5, 13, 44, 66, 123, etc
Try Union like this
(SELECT * FROM employee WHERE id < 5 order by id DESC LIMIT 1)
UNION
(SELECT * FROM employee WHERE id >5 LIMIT 1)
PHP
$id = 5;
SELECT * FROM Employee where id = $id-1 OR id = $id+1;
MySQL
SET #id = 5;
SELECT * FROM Employee where id = #id-1 OR id = #id+1;
Checkout find('neighbors'). It returns the records before and after the one you specify and your ids can have "holes" in the sequence.

Select count for each distinct row (mysql and php)

I am using mysql and php.
I have a table with one column. I can show unique rows by:
select distinct id from id_table
This might show
1
2
3
5
What I want to do is show the number of 1's, 2's, etc there are.
I could do
select count(id) from id_table where id = 1
But then I have to run a query for every... single... row... And with hundreds of thousands of rows, not good.
Is there a way to return an array of the counts of each distinct item
Data
1, 1, 1, 2, 3, 3, 5
Results
3, 1, 2, 1
Thanks
select id, count(id)
from table
group by id
If only want count of ids, then
select count(id)
from table
group by id
Here is a simple tutorial of group by clause
http://www.w3schools.com/sql/sql_groupby.asp

ordering mysql table for the max of two variables

hope someone can help me with this issue.
I have a table with two columns, and i want to select items from that table and order them depending on which of these two values is higher.
lets say i have columns 'x' and 'y' and i have these entries:
x ; y
1.- 10 ; 12
2.- 5 ; 10
3.- 11 ; 20
i want the response to be ordered: 3, 1, 2
i know this wont help, since it has no sence in the mysql, but is a representation of my idea
$query = (mysql_query("SELECT * FROM productos ORDER BY MAX(x, y)"));
i dont want to create a new variable in the table for this query.
Any idea? thanks a lot
You want to sort it after x or y, depending which is higher?
SELECT * FROM products ORDER BY GREATEST(x, y)
But in your case this is 3, 2, 1 because 15(y) is higher than -5(x) and also higher than the greatest in row 1. So I am a bit confused.
Supporting NULLs and correct order:
SELECT * FROM products ORDER BY GREATEST(COALESCE(x, 0), COALESCE(y, 0)) DESC
If you need other value as default than 0 just replace it.
Select
*
from
products
order by
Case when x>y then x else y end DESC
SELECT *
FROM products
ORDER BY GREATEST(x,y) DESC
, LEAST(x,y) DESC
The second part of the ordering (LEAST) is to put a row with (12,20) before a row with (10,20).
Since the two fields can have NULL:
SELECT *
FROM products
ORDER BY GREATEST( COALESCE(x,0), COALESCE(y,0) ) DESC
, LEAST( COALESCE(x,0), COALESCE(y,0) ) DESC ;

Categories