I have the following tables in my database:
Table: Employee
ID Name
-- ----
1 Mike
2 Peter
3 Daniel
Table: Location
EmployeeID City
---------- ----
1 Berlin
1 Stuttgart
1 München
2 Hamburg
3 Stuttgart
3 Berlin
The Employee table contains information about the employees. The Location table contains information about the locations the employees have their projects in (e.g Mike has projects in Berlin, Stuttgart, and München).
What I want to do now is to filter employees by given locations in an array but still retrieve all the locations of each employee. For example, filtering by the array ["Berlin", Stuttgart] should return the following result:
ID Name City
-- ---- ----
1 Mike Berlin, Stuttgart, München
3 Daniel Stuttgart, Berlin
I know that I can use GROUP_CONCAT() to concatenate the locations. But how can I do the filtering? I need to be able to do it using SQL.
Apply WHERE condition to get EmployeeID from Location table:
SELECT
Employee.*,
GROUP_CONCAT(Location.City)
FROM
Employee
INNER JOIN Location
ON Employee.ID=Location.EmployeeID
INNER JOIN
(SELECT DISTINCT
EmployeeID
FROM
Location
WHERE
City IN ('Berlin', 'Stuttgart')) AS IDS
ON Employee.ID=IDS.EmployeeID
GROUP BY
Employee.ID
-check the fiddle.
Alternative solution would be to use HAVING clause with plain query and INSTR(), for example, but I don't recommend you to do it because comparing in HAVING will be slow and, besides, list of values will produce multiple comparisons.
You can use below query:
SELECT
a.id,a.`name`,GROUP_CONCAT(b.city)
FROM employee a
JOIN
(SELECT DISTINCT employeeid,city FROM location WHERE location IN ('Berlin', 'Stuttgart')) b
ON a.id=b.employeeid
GROUP BY a.id;
Related
SELECT (SELECT GROUP_CONCAT(companyName)FROM company WHERE id IN (27,38)) AS companyName, t.*
FROM Test t
it return output like this,
>Apple, Sony
But if I pass the id as full string,
SELECT (SELECT GROUP_CONCAT(companyName)
FROM company WHERE id IN ("27,38")) AS companyName, t.*
FROM Test t
So it return first company name only, so output like this
>Apple
I want to retrieve the data like this Apple, Sony.(Like first query), How can I achieve this one?
Sample Table Structure below
company Table
--------------------
ID companyName
-------------------
27 Apple
28 Sony
. .
. .
You are passing 27 and 28 as single string so MySQL consider the first number which is 27, that's why it's returning apple. If you want return Apple and Sony you have to split the string.
You need to use
SELECT group_concat(companyName separator ',')
FROM company WHERE id IN ("27,38");
I saw your comments it looks like you are storing company ids for Trailers as a comma separated string which is against of normalization, Instead you can add new junction table which hold the reference of both tables company and trailers like
trailer
=======
id name
1 some name
company
id name
-------------------
1 Apple
2 Sony
trailer_companies (junction table)
trailer_id company_id
---------------------
1 27
1 38
Now you can query records by using joins
select t.*,group_concat(c.name) companyName
from trailer t
join trailer_companies tc on (t.id = tc.trailer_id)
join company c on (tc.company_id = c.id)
group by t.id
DEMO
If you want to continue with your current design which is strongly not advisable because it will be hard to optimize and not fit for scaled apps
SELECT
(SELECT
GROUP_CONCAT(companyName SEPARATOR ',')
FROM company
WHERE FIND_IN_SET(id,t.companyIds) > 0
) AS companyName, t.*
FROM Trailers t
I would like to create a sql query which create a column that doesn't exists in the db tables and gets fills on whether a row exists or not exists in a specific table.
For example:
I have 3 tables:
Users (For users list) - UID, UName
Locations (List of all available locations) - LID, LName
UsersLocations (All the locations the users have checked into) - UserID, LocationID
I need a sql query that from a user id get me a table of all the locations with a column that says whether the user has been in this location or not.
Example for Users table
UID | UName
1 John
4 Amy
5 Dann
Example for Locations table:
LID | LName
1 London
2 Barcelona
3 Paris
4 New York
Example for UsersLocations table:
UserID | LocationID
5 1
5 2
Example for output (for userid = 5):
User ID | Location | Was Here
5 London true
5 Barcelona true
5 Paris false
5 New York false
The output needs to include all the Locations from the locations table.
Also the UsersLocations table only contains the userID of the users that checked into that location.
Hmmm. One method is a correlated subquery:
select u.userid, l.location,
(case when exists (select 1 from userLocations where ul.userid = u.userid and ul.lid = l.locationid)
then 'true'
else 'false'
end) as WasHere
from location l cross join
(select 5 as userid) u;
The only part that is database-specific is the subquery for u.
I have two tables
1. studentprofile
sud_id name
1 kp
2 kishan
3 raj
2. fee_generate
fee_id stud_id fee_balance name
1 1 0 kp
2 2 10 kishan
I want to show those students whose fee is not submitted or have any balance, which means that I want to show is as following
kishan and raj
I am not able to write the query with any join. My second problem is that name columns are common in both tables.
So the selected name column should come from studentprofile table and order by name from studentprofile table.
You need to left join the fee_generate table on the student_profile table and include those records where the fee_generate.student_id is null (not submitted) or the balance is over 0:
select s.* from student_profile s
left join fee_generate f on s.stud_id=f.stud_id
where f.stud_id is null or f.balance>0
order by f.name
In mp_cities table city_name and city_id are the fields
city_id city
--------------------
1 Chennai
2 Bangalore
3 Kerala
In profile table
user_email city_type
------------------------------
abc#gmail.com 1,2,3
I am using the following query
SELECT city_name
FROM mp_cities
WHERE city_id IN (SELECT city_type
FROM profile
WHERE user_email='abc#gmail.com')
this query will result Chennai.
I have to get all the cities
You can use FIND_IN_SET() in MySQL.
SELECT a.*
FROM mp_cities a
INNER JOIN profile b
ON FIND_IN_SET(a.city_id, b.city_type)
WHERE b.user_email = 'abc#gmail.com'
but the best way so far I can think is to normalize the table properly.
mp_cities
city_id (PK)
city
other columns
profile
user_id (PK)
other columns
mp_cities _profile
city_id (FK)
user_id (FK)
You would get the desired result if the profile table looked like this:
user_email city_type
------------------------
abc#gmail.com 1
abc#gmail.com 2
abc#gmail.com 3
That is, the inner SELECT must return several rows, each with a number, NOT one row with a comma-delimited set of numbers.
Try to join both tables with FIND_IN_SET() function like this:
SELECT c.*
FROM mp_cities c
JOIN profile p
ON FIND_IN_SET(c.city_id,p.city_type) > 0;
See this SQLFiddle
I have a situation which deals with two sets of data with different columns. I know I could use UNION but UNION requires equal number of expressions in both tables. I am trying to join these two statements in my stored procedure. The first statement has one Extra Column 'Location'
Select
TableA.Name,
TableB.Occupation,
TableA.Location,
'Group1' AS [groupBy]
From
TableA,
TableB
Where
TableA.ID = 1
Select
TableA.Name,
TableB.Occupation,
'Group2' AS [groupBy]
From
TableA,
TableB
Where
TableB.ID = 10
My result should look like this
Name Occupation GroupBy Location
David Doctor Group1 USA
John Pilot Group1 Asia
Dwayne Wrestler Group2 NULL
Axel RockStar Group2 NULL
My Table structure
Table A
ID Name Occupation Location
1 David Doctor USA
1 John Pilot Asia
2 Mike Clerk Europe
Table B
ID Name Occupation
3 Wayne Writer
4 Shane Publisher
10 Dwayne Wrestler
10 Axel Rockstar
That's called a UNION; just manually add ", NULL" to the select list in the second query
Add as many of them as you need, whereever you need them. If you need additional columns in both tables, instances of NULL in the first table must be aliasd with the appropriate column name.