SELECT as alias to another SELECT - mysql

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

Related

How to select multiple fields in MySQL query when using INNER JOIN

I want to select multiple fields from table p.
The second line of this code is wrong. how to write?
except p.*
I don't want p.*
SELECT
p.id, title, price
c.`title` as `CategoryTitle`
from `tbl_products` p
INNER JOIN `tbl_categories` c
ON p.`category_FK` = c.`id`
Well, you might have your own reason so, perhaps you can do something like this:
SELECT
id, title, price, CategoryTitle
FROM `tbl_products` p
INNER JOIN
(SELECT `title` AS 'CategoryTitle', id AS 'CategoryID'
FROM `tbl_categories`) c
ON category_FK = CategoryID
Make one of the table as a subquery and define column alias that's not a duplicate with the other table. In your example, it seems like both of your tables have columns with similar names like id & title. Once you define those similar column names in the subquery with different alias, then you won't need to do p.xx or c.xx.

MySQL How to order by column name

I have two MySQL Tables. In this abstract example I will use these to explain my issue:
Persons(person_id, name);
Competition(competition_id, first, second, third);
First, second and third refer to person_id and I want to get the names in this order. If I use
SELECT name
FROM Persons
, Competition
WHERE person_id = first
OR person_id second
OR person_id = third;
the names are sorted by their table order (usually the same order like sorted by primary key). How can I order them right?
Edit:
I need to enter a competition_id and want to get a table with three name lines in the right order
I think you just need multiple joins:
SELECT c.*, p1.name, p2.name, p3.name
FROM Competition c LEFT JOIN
Persons p1
ON p1.person_id = c.first LEFT JOIN
Persons p2
ON p2.person_id = c.second LEFT JOIN
Persons p3
ON p3.person_id = c.third;
This puts the names for a given row in competition in the same row. That seems like a sensible thing to do.
EDIT:
If you want the first matching name, you can use COALESCE():
SELECT c.*, COALESCE(p1.name, p2.name, p3.name)
The solution is, a seperate table is required.
Persons(person_id, name);
Mapper(pk_mapper_id, fk_competition_id, fk_person_id, rang)
Competition(competition_id);
Here I can order by rang.

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

More than one value in the same row 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

Display the details from one table and count from another table

need to fetch id, name, address details of a man from one table and and number of properties from another table belonging to him
we tried this way
select person.* count(property.id) from person, property where person.id = property.id
This is how you should do it
select person.id, person.name, person.address,
count(property.id)
from person
left join property on person.id = property.id
group by id, name, address
Group by all fields that are not aggregated (counted). And then use the explicit join syntax. The other is just outdated since decades.