MYSQL query data and combine, group and order results - mysql

I am having trouble getting a query to work effectively which only queries 1 table. Here is an example of the table data:
ID NAME PARENT_ID SORT_ORDER
1 Home NULL 1
2 Contact NULL 3
3 Service NULL 2
4 Service1 3 0
5 Service3 3 2
6 Service2 3 1
What I would like to do is to return the data from this table with results that have a PARENT_ID appearing under the result with that ID, and to have all results then display in their SORT_ORDER. Here is how I would like the query to result the above data:
ID NAME PARENT_ID SORT_ORDER
1 Home NULL 1
3 Service NULL 2
4 Service1 3 0
6 Service2 3 1
5 Service3 3 2
2 Contact Null 3
Any feedback to make this happen is very welcome.
Kind regards,
Paul

If I understand your logic correctly, you could use this:
SELECT
t1.*
FROM
yourtable t1 LEFT JOIN yourtable t2
ON t1.PARENT_ID = t2.ID
ORDER BY
COALESCE(t2.SORT_ORDER, t1.SORT_ORDER),
t1.PARENT_ID IS NOT NULL,
SORT_ORDER
Please see fiddle here.

Related

Need MySql query that should return result by ordering values in particular field

Need MySql query that should return result by ordering values in particular field.
From below my result set should contain order like parent_id (1,4,6) should come first parent_id(2,3,7) come next and other should come last.
d data parent_id
----------------------
1 a1 1
2 abc 3
3 abcd 4
4 xyz 2
5 zxyy 6
2 abc 8
3 abcd 9
4 xyz 2
5 zxyy 15
Use a CASE expression in your ORDER BY clause:
SELECT d, data, parent_id
FROM yourTable
ORDER BY CASE WHEN parent_id IN (1, 4, 6) THEN 1
WHEN parent_id IN (2, 3, 7) THEN 2
ELSE 3 END,
parent_id
Follow the link below for a running demo:
SQLFiddle
Use below mentioned query
SELECT d, data, parent_id FROM table_name ORDER BY FIELD(parent_id,1,4,6,2,3,7);

Mysql statement, if at least one row contains result

i've a table with records:
----------------------------------
ID | UniqueId | Name | Result
----------------------------------
1 1 Test1 OK
2 1 Test1 Cancelled
3 1 Test1 OK
4 2 Test2 OK
5 2 Test2 OK
6 2 Test2 OK
7 2 Test2 OK
8 3 Test3 OK
9 3 Test3 OK
Let's say i wan't to check if at least one row with UniqueId = 1 not contains Result == Cancelled. To exclude record with UniqueId = 1, because it is cancelled.
How can i do this?
Thank you
SELECT t1.* from table as t1 where t1.UniqueId not in(select t.UniqueId from table as t
where t.Result="Cancelled")
Just ask for rows with UniqueId = 1 and Result != Cancelled
SELECT ID FROM table WHERE UniqueId = 1 AND Result <> 'Cancelled' LIMIT 1
I'd go this way, but the other answers are a bit easier in terms of syntax.
SELECT UniqueId, Name
FROM Table T
GROUP BY UniqueId, Name
HAVING Result != 'Cancelled'
SELECT id FROM mytable WHERE uniqueId = 1 AND result != 'Cancelled'

first item used by a user

I am writing a query to grab the items that a specific user_id was the first to use. Here is some sample data -
item_id used_user_id date_used
1 1 2012-08-25
1 2 2012-08-26
1 3 2012-08-27
2 2 2012-08-27
3 1 2012-08-27
4 1 2012-08-21
4 3 2012-08-24
5 3 2012-08-23
query
select item_id as inner_item_id, ( select used_user_id
from test
where test.item_id = inner_item_id
order by date_used asc
limit 1 ) as first_to_use_it
from test
where used_user_id = 1
group by item_id
It returns the correct values
inner_item_id first_to_use_it
1 1
3 1
4 1
but the query is VERY slow on a giant table. Is there a certain index that I can use or a better query that I can write?
i can't get exactly what you mean because in your inner query you have sorted it by their used_user_id and and on your outer query you have filtered it also by their userid. Why not do this directly?
SELECT DISTINCT item_id AS inner_item_id,
used_user_id AS first_to_use_it
FROM test
WHERE used_user_id = 1
UPDATE 1
SELECT b.item_id,
b.used_user_id AS first_to_use_it
FROM
(
SELECT item_ID, MIN(date_used) minDate
FROM tableName
GROUP BY item_ID
) a
INNER JOIN tableName b
ON a.item_ID = b.item_ID AND
a.minDate = b.date_used
WHERE b.used_user_id = 1

MySQL: Select User Only If They Completed All Items?

I have a two tables: users and missionInfo. I need to select classes only when all of the users who are in that class completed all missions.
users table:
userID classID
1 1
2 1
3 1
4 2
5 2
missionInfo table:
userID missionID
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
4 1
5 1
5 2
So, I should get back classID 1 because users 1 thru 3 all completed all missions 1 thru 3 and are all part of the same class.
Help?
SELECT classID FROM (
SELECT classID
FROM users JOIN missionInfo USING (userID)
GROUP BY classID, missionID
HAVING COUNT(DISTINCT userID) = (
SELECT COUNT(*) FROM users u WHERE u.classID = users.classID
)
) AS t
GROUP BY classID
HAVING COUNT(*) = #total_number_of_missions
See it on sqlfiddle.
The DISTINCT can be omitted if (userID,missionID) will only appear once in the missionInfo table.
The inner query returns classID for every mission that has been completed by all that class's users; the outer one restricts the results to only those classes who have completed the specified number of missions.

Selecting rows with reference id's to same table from mysql

I have a table such as:
id name ref_id order data_obj
-- ---- ------ ----- --------
1 Sam 0 15 [binary data]
2 Jack 0 20 [binary data]
3 Sue 0 25 [binary data]
4 Sam2 1 - [no data]
5 Sue2 3 - [no data]
6 Sam3 1 - [no data]
The idea is that I have more columns other than data_obj which can be common, so I don't want to insert them again, just want to insert a reference id to the same data.
Is it possible to write a query and select this:
1 - Sam - binary data from id 1
4 - Sam2 - binary data from id 1
6 - Sam3 - binary data from id 1
2 - Jack - binary data from id 2
3 - Sue - binary data from id 3
5 - Sue2 - binary data from id 3
Please note that I'm ordering according to column named order and there's no actual data for this column for referenced rows.
SELECT t1.id, t1.name, t2.data_obj
FROM your_table t1
LEFT JOIN your_table t2 ON t1.ref_id = t2.id
ORDER BY t1.order
Other version, which doesn't return rows without ref
SELECT t1.id, t1.name, t2.data_obj
FROM your_table t1, your_table t2
WHERE t1.ref_id = t2.id
ORDER BY t1.order
Here's a modification of #vartec's answer. This modification uses COALESCE() to combine the data_obj from either the primary row or the referenced row.
SELECT t1.id, t1.name, COALESCE(t1.data_obj, t2.data_obj)
FROM your_table t1
LEFT JOIN your_table t2 ON t1.ref_id = t2.id
ORDER BY COALESCE(t1.order, t2.order), ref_id;
COALESCE() is a standard SQL function that returns its first non-NULL argument.
Why aren't you using more than one table?
CREATE TABLE user (
user_id number not null (some form of auto increment or sequence),
name varchar(50) not null,
otherdata type,
primary key (id));
CREATE TABLE common (
common_id number not null (autoinc),
user_id number not null,
commondata type,
primary key (common_id),
unique index (user_id, common_id));
SELECT u.name, u.otherdata, c.commondata
FROM user u, common c
WHERE u.user_id = c.user_id
TABLE user
user_id name otherdata
1 Sam abc
2 Jack def
3 Sue ghi
Table common
common_id user_id commondata
1 1 AAA
2 1 BBB
3 1 CCC
4 2 DDD
5 3 EEE
6 3 FFF
Output
name otherdata commondata
Sam abc AAA
Sam abc BBB
Sam abc CCC
Jack def DDD
Sue ghi EEE
Sue ghi FFF