More than one value in the same row MYSQL - mysql

my problem is the next:
I have a sql query that shows information about a booking. The info is the name of the person who made the reservation, phone, etc and the extras he bought.
I need to show all the extras he bought on the same row but i cant find a method for it (im not very good at mysql)
So, i have two tables : 1 for the general info of the booking and another for the extras info because one reservation can have more than one extra and one extra could be on more than one reservation.
Table booking:
id,name,telephone
table booking_extra:
id, id_extra, id_booking
i want to
select * from booking
left join booking_extra on id_booking = booking.id
and the result should be something like
id:1
name: test
telephone: 123456
extras: 1,2,3
any ideas?

As #panther hinted in the comment, use group_concat. So you query will be like:
SELECT A.ID, A.NAME, A.TELEPHONE,
GROUP_CONCAT(DISTINCT B.ID_EXTRA ORDER BY B.ID_EXTRA ASC SEPARATOR ',') EXTRAS
FROM BOOKING A LEFT JOIN BOOKING_EXTRA B ON A.ID=B.ID_BOOKING
GROUP BY A.ID, B.ID_BOOKING;

Something like this :
SELECT id, name, telephone, GROUP_CONCAT(extras, separator ',')
FROM booking
LEFT JOIN booking_extra ON id_booking = booking.id
GROUP BY id, name, telephone

Related

JOIN Statement For Multiple Tables Not Working

I just started learning SQL last night. I'm having trouble displaying data using multiple JOIN statements. The tables I have are:
Table: CUSTOMER
Contains CustomerID, Country, Last Name
Table: TRANS
Contains CustomerID, TransactionID, DateSold, WorkID
Table: WORK
Contains WorkID, Title, Description
Here's my query:
Select CUSTOMER.LastName, CUSTOMER.CustomerID, WORK.WorkID,
Description, Title
FROM CUSTOMER JOIN TRANS
ON CUSTOMER.CustomerID = TRANS.CustomerID
JOIN WORK
ON TRANS.WorkID = WORK.WorkID
WHERE DateSold = '11/17/2014'
GROUP BY CUSTOMER.CustomerID, TRANS.CustomerID, CUSTOMER.LastName,
WORK.WorkID, Title, DateSold, Description
Note that in the select statement, I've deliberately left out a few items that appear in the GROUP BY statement, just for the sake of this post. (Their inclusion in the SELECT statement doesn't cause program to execute properly.)
All that appears is the GROUP BY statement, but no actual data. Please help me with what I'm doing wrong. Thank you.
Use the STR_TO_DATE function in mysql to convert the date string.
WHERE DateSole = STR_TO_DATE('11/17/2014', '%m/%d/%Y')
You can join one table with two different table but you have to start from the common table.
For how you wrote the query you are saying to join CUSTOMER first with TRANS and then with WORK but the conditions are wrong for this situation (and it is not what you want to do).
Select CUSTOMER.LastName, CUSTOMER.CustomerID, WORK.WorkID,
Description, Title
FROM TRANS JOIN CUSTOMER
ON CUSTOMER.CustomerID = TRANS.CustomerID
JOIN WORK
ON TRANS.WorkID = WORK.WorkID
WHERE DateSold = '11/17/2014'
GROUP BY CUSTOMER.CustomerID, TRANS.CustomerID, CUSTOMER.LastName,
WORK.WorkID, Title, DateSold, Description
It is TRANS that you join first with CUSTOMER and then with WORK.

Joining tables in MySQL and requesting data from second table only

I'm trying to join 2 tables where I need to show only 3 columns from the second one where another column is used as a comparison.
For example:
Table one is called employee: it has a column called user_id and some other columns
Table two is called people: it has a column called user_id which included some of the employees user_ids
The columns I want to select are all from table people! (firstname, lastname, email)
I tried the following but something going wrong:
SELECT userid, firstname, lastname, email
FROM people
JOIN employee
WHERE people.userid = employee.userid;
I'm not sure what am I doing wrong, could you please help me correct it?
You can try this query:
SELECT
p.userid,
p.firstname,
p.lastname,
p.email
FROM
people as p,
employee as emp
WHERE
p.userid = emp.userid
Looking at your script, it looks like you'll run into ambiguous columns in at least your userid. You want to explicitly tell SQL where the column comes from like in your WHERE clause if there are columns sharing the same name between the two tables.
SELECT
userid, -- AMBIGUOUS
firstname,
lastname,
email
FROM people
JOIN employee
WHERE people.userid = employee.userid;
Example solution:
SELECT
people.userid,
people.firstname,
people.lastname,
people.email
FROM people
JOIN employee
WHERE people.userid = employee.userid;
For this issue you can use this query
let suppose that I have a users table where a user have zero to one profile picture
I need the user (Name,LastName,BirthDate) for users who have no profile picture
I can use this query
select *
from user c
where NOT EXISTS (
select 1
from photo p
where p.id = c.photo_id
)
in this where you can use any field between this two table
removing the not will result on the users who have a profile picture
hope this help you
you can search for SEMI JOIN and ANTI JOIN for more informations
i think this query will solve your problem
insert into table1 (clmn_1,clmn_2,clmn_3) SELECT clmn_1,clmn_2,clmn_3 FROM table2 where id = value

SELECT as alias to another SELECT

I have two tables in a relation "one to many".
So in table person I have id, name, etc and in table tags I have id, personid, tag
And one person can have N entries with different tags.
I thought I could do something like
SELECT id, name,
(SELECT * FROM tags WHERE personid = id) AS tags
FROM person
And I expect to receive a result row with NUMBER(id), STRING(name), ARRAY(tags).
I know how to do this with a for loop, with 2 separate queries but I think MySQL should be best to do this.
If I do a JOIN I end up with many rows, bu I want to group all tags in a array-like entry of each row I get, ie. one row per person.
Is this possible?
You can use GROUP_CONCAT with GROUP BY id
http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_group-concat
Something like this:
SELECT person.id, person.name,
GROUP_CONCAT(tags.name SEPARATOR ', ') FROM person
INNER JOIN tags ON tags.personid = person.id
GROUP BY person.id

"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