Mysql join problem between 5tables - mysql

Sorry for my english, I'm from austria, but I couldn't find another nice q&a-board. :)
I have a very strange structured mysql-database.
First there is a table for users, for my example there are only three colums interesting:
id, name, email
My second table is a table for events: id, name
My third table is a category-table for events: id, name, eventID
My fourth table is a undercategory-table for events: id, name, catID
My fifth table is a time-table for events: id, name, ucatID
My sixth table is a table, where a entry combines a time with a person
Its a plan for work, in some way...
users: id, name, email
events: id, name
categories: id, name, eventID
undercategories: id, name, catID
underundercategories: id, name, ucatID
table to join: id, userID, uucatID
Yeah I have, so far, every entry (user-name, ucat-name, uucat-name) ...
but I'm trying to get a list of persons who have no entry in the join-table! (but only, where the eventID is ... say 1^^)
Here is my code for the list where there is an entry:
SELECT a.*,b.name,c.name AS zeit,d.name AS kategorie
FROM intern_user AS b
INNER JOIN intern_dienstplan AS a ON a.userID=b.id
INNER JOIN intern_events_uucat AS c ON a.uucatID=c.id
INNER JOIN intern_events_ucat AS d ON c.ucatID=d.id
INNER JOIN intern_events_cat AS e ON d.catID=e.id
WHERE e.eventID='".$_POST['eventid']."'
ORDER BY b.name ASC
I hope someone can help me... I have already tried something with "a.id is null" (where is no entry in join-table), but it doesn't work.

A long time has gone... and I have found the solution for my problem. :]
Here the code, for others with the same problem...
SELECT *
FROM intern_user
WHERE
(
id NOT IN
(
SELECT a.userID
FROM intern_dienstplan AS a
INNER JOIN intern_events_uucat AS b ON a.uucatID=b.id
INNER JOIN intern_events_ucat as c ON b.ucatID=c.id
INNER JOIN intern_events_cat AS d ON c.catID=d.id
WHERE d.eventID='".$_POST['eventid']."'
GROUP BY a.userID
HAVING sum(b.wert) >= 100
)
)
AND status='1'
Thanks for all help and have fun with this shit. :D
Greets

It's not clear what is type of connection for categories-subcategories-subsubcategories.
How much subcategories could have the event (0-1-N)?
If you just want to find persons who do not have matched record in link table, you can use a query:
select a.*
from user a
left join link b on a.id = b.userId
where b.userId is null
or
select a.*
from user a
where id not in (select userId from link)
Update. Still do not have answer for the question above.
You can try:
select *
from users
where id not in (
select link.userId
from event a
inner join categories ...
inner join subcategories ...
inner join categories ...
inner join link ...
where a.eventId = ...)
It could be easy transformed to versions with left join or exists().

Related

Join with SELECT MySQL

I need a way to join a table with the results of a SELECT query, and I'm facing some difficulty to do that ...
There are 3 tables:
food_shops
id, name, slug
categories_food_shops
id, id_category, id_food_shop
categories
id, name, slug
How can I do to show a result with: food_shop.id, food_shop.name, categorie.slug
based on the categories_food_shops table? that contains a registry of the shop and their category?
so far I was able to do this, but it gets
Unknown column 'fs.id' in 'where clause'
SELECT fs.id, fs.slug, fs.name
FROM food_shops fs
JOIN
(
SELECT *
FROM categories_food_shops cfs
WHERE cfs.id_food_shop = fs.id
) AS cfs ON categories.id = cfs.id_catedory
Any help would be very appreciated, I'm new to this join statements
Try this:
SELECT
food_shops.id, food_shops.name, categories.slug
FROM food_shops
INNER JOIN categories_food_shops
ON food_shops.id = categories_food_shops.id_food_shop
INNER JOIN categories
ON categories_food_shops.id_category = categories.id
You can then use a WHERE statement at the end to display food shops with a specific id, or with a similar name, etc.

display row where id is not displayed

Using one table, I am trying to run a query that matches a userid to a course.
The goal is to see the courses that the userid is not in,
So far I can display the usid's that are not in all the courses, but now I want to display the courses that they are not in
SELECT usid, course, COUNT(*)
FROM COURSE_COMMENTS
WHERE course in (1,2,3,4,5,6,7,8)
GROUP BY usid
HAVING COUNT(*) < 8
Also, neither usid, nor course are primary so they can show up multiple times.
any ideas?
If you have a courses table, you can do something like this:
select u.usid, c.course
from (select distinct course from courses where course in (1,2,3,4,5,6,7,8)) c cross join
(select distinct usid from course_comments) u left join
course_comments cc
on cc.course = c.course and cc.usid = u.usid
where cc.course is null;

How to write a sql query to get data from two tables

I want to get numOfItem from table BUY using ticketTypeId and then using the BUY.userId to find in the table USER to get the gender. So I can get numOfItem from table BUY and gender from table USER. I don't know how to write this in one query. Any idea?
table structure:
TABLE BUY:
ticketTypeId
numOfItem
userId
TABLE USER:
gender
You need to join your tables on a common field, in this case user id
Select b.ticketTypeId, b.numOfItem, b.userId, u.gender
From buy b inner join user u on b.userid = u.userid
Where b.ticketTypeId = <val>
You want to include where to get only needed ticketTypeId
Generally speaking a join between two tables is something like:
select table1.*,table2.*
from
table1
join table2 on table1.key=table2.key
Add userId in the table user
join the tables with inner join in the select statement
select a.*,b.* from [user] a inner join [buy] b on a.userid = b.userid
You need to use a join. Here is an link
SELECT tb1.ticketId, tb1.numOfItem, tb1.userId, tb2.gender
FROM Table1 as tb1
JOIN Table2 as tb2
ON tb1.userId = tb2.userId

"Join" admins of different tables into a string

The real issue
Involved tables and their columns
accounts [id,name]
rooms [id,name,topic,owner]
room_admins [account_id,room_id]
Q: Get all rooms with their admin- and owner ids.
Where "all" of course has a condition to it (above: WHERE name LIKE ...)
Admins and owners should be returned in one column just called "admins". I tried to concatenate them above into one string.
What I tried
I came up with a solution, but it requires the use of an omnious external variable ":room_id" that changes on each outer SELECT and makes therefore no sense at all.
SELECT id,name,topic,
(SELECT GROUP_CONCAT(admins.account_id) AS owner
FROM
(SELECT account_id
FROM `room_admins`
WHERE room_id=:room_id
UNION
SELECT owner FROM `rooms` WHERE id=:room_id) admins) AS owner
FROM `rooms`
WHERE name LIKE "%htm%" OR topic LIKE "%htm%" LIMIT 20
Well, I haven't given this a deep thought... but I've just came up with this (sample data would have been useful to make tests... so this is just a blind answer).
select id, name, topic, group_concat(owner_admin) from (
select id, name, topic, owner owner_admin from rooms
union
select id, name, topic, account_id from rooms
left join room_admins on id = room_id
) s
where name like "%htm%" or topic like "%htm%"
group by id, name, topic
Basically I'm just generating a derived table with owner and admins mixed in one column. Then performing the grouping on that mixed column.
Most of the times, when you want to select and display dependent data, you want to use a JOIN. In this case, you want to join the rooms with their admins, so basically:
SELECT r.id, r.name, r.topic, a.id
FROM rooms r
LEFT JOIN admins a
ON r.id = a.room_id
WHERE :condition
Since you have one additional admin not in the admins table (the room owner), you have to (self) join a second time:
SELECT r.id, r.name, r.topic, a.id
FROM rooms r
LEFT JOIN admins a
ON r.id = a.room_id
LEFT JOIN rooms o
ON r.id = o.id
WHERE :condition
This doesn't give us any new information, but your question states that you want to return the list of admins in a single field. So, finally, putting it all together:
SELECT r.id, r.name, r.topic, GROUP_CONCAT(a.id)
FROM rooms r
LEFT JOIN
(
SELECT id, room_id FROM admins
UNION SELECT room.owner AS id, rooms.id AS room_id FROM rooms
) a
ON r.id = a.room_id
WHERE :condition
GROUP BY r.id
But to avoid this ugly sub-select-union clause, I'd advise you to put the room owner into your admin table too.

complex(?) mysql correlated counting query. please help?

Suppose the following situation.
Persons assigned to tasks, and I want to return Person id, Person Name, the number of tasks completed by each person from the following tables.
Table Name - Field Name
Person - id, Name
Task_Person_Combi - Task_id, Person_id
Task* - returns id of Task (actually this is LEFT Joined table which returns id of persons)
(Task has over 100,000 rows, and the query has to be quick well less than 1 second)
After reading MySQL statement combining a join and a count?, I'm trying the following. (but this doesn't seem to work, and I'm kind of lost)
SELECT id, Name,
(
SELECT COUNT(*)
FROM Task_Person_Combi C
WHERE P.id=C.Person_id AND C.Task IN (SELECT id FROM Task* - this is Joined table)
) AS Count
FROM Person P
WHERE id>0
HAVING Count>0
ORDER BY Name
Please help.
Try this?
SELECT id, Name,
COUNT(T.ID) AS TaskCount
FROM Person AS P
INNER JOIN Task_Person_Combi AS C ON P.id=C.Person_id
LEFT JOIN TASK AS T ON C.Task = T.id
WHERE id>0
AND T.id IS NOT NULL
GROUP BY id,Name
HAVING COUNT(T.ID)>0
ORDER BY Name