Display the details from one table and count from another table - mysql

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.

Related

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

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

Need verification for a query

I have three tables
Clients:
Client ID
First name
Last name
Transactions:
Trans ID
ClientID
RepresentativeID
Order ID
Representatives:
Representative ID
First name
Last name
I need to display all of the transactions information, with the representative name and client name that occurred in a specific date. Is this query right?
SELECT *
FROM [Transactions], Clients.first name, Clients.last name, Representatives.first name, Representatives. last name
INNER JOIN [Clients]
ON Transactions.ClientID= Clients.Client ID
INNER JOIN [Representatives]
ON Transactions.RepresntativeID = Representatives.Represntative ID
WHERE Transactions.OrderDate BETWEEN '1996-09-18' AND '1996-11-27';
Is that right or did i get all wrong?
Joining conditions are fine. However, depending on type of OrderDate column you may need to use MySQL's STR_TO_DATE function, e.g.:
WHERE STR_TO_DATE(`OrderDate`,'%d-%m-%Y')
BETWEEN '1996-09-18' AND '1996-11-27'
Update
We also need to update SELECT and FROM syntax:
SELECT t.Trans_ID, c.first name, c.last_name, r.first name, r.last_name
FROM Transactions t INNER JOIN Clients c on t.ClientID= c.Client_ID
INNER JOIN Representatives r
ON t.RepresntativeID = r.Represntative_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.