How to use IN query? - mysql

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

Related

SQL- Top count(column1) w.r.t Distinct column2

I have a table with three columns,
| User_id (INT) | CountryCode (VARCHAR) | channel_accessed (VARCHAR) |
There is no primary key over here, so repetition is possible for all columns.
I want to write a SQL query that returns Top countries name & there corresponding count w.r.t unique User_id
Tried following this Using group by on multiple columns but this has not helped me much.
sample data :
| User_id (INT) | CountryCode (VARCHAR) | channel_accessed (VARCHAR) |
1 US ARY
2 CA ARY
3 CA MTV
2 CA HUMTV
4 US Tensports
5 US Star Sports
2 CA PTV
2 CA QTV
2 CA NATGEO
Expected Result : US, because it has more unique users.
Try this:
select CountryCode
from yourtable
group by CountryCode
order by count(distinct User_id) desc
limit 1
SQLFiddle Demo
If the channel_accessed column doesn't matter then you could try
SELECT CountryCode, MAX(user_count)
FROM (SELECT CountryCode,
COUNT(DISTINCT(user_id)) as user_count
FROM table_name
GROUP BY CountryCode)

MySQL IN operator of result from another column

I have 2 tables:
users(uid, name, titles)
titles(uid, name)
users:
uid | name | titles
1 David 2,4
2 John 5
3 Jane 4
titles:
uid | name
2 Owner
4 CEO
5 Manager
The question is how do I select something like this:
SELECT u.* FROM users as u
JOIN titles as t
ON t.uid IN (u.titles)
WHERE t.uid=2
Notice the IN(u.titles)? It's only taking the first title uid in u.titles field. That means when I change condition to WHERE t.uid=4, it shows no records.
Any idea?
SELECT u.*
FROM users as u
JOIN titles as t ON find_in_set(t.uid, u.titles) > 0
WHERE t.uid=2
If you want that each user can have multiple titles I would recommend a reference table which references the users to the titles.

SQL filtering using an array

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;

Joining the same table to get the information

I have a table like
Name Spouse
---------------
John Smitha
Bob Neetha
Neetha Bob
Mona Jack
Smitha John
Jack Mona
and I want results as below using joins in MySQL.
Name Spouse
---------------
John Smitha
Bob Neetha
Mona Jack
(i.e. the couple should be selected only once)
Assuming that you have a IsPrimary field.
You could easily achieve this with the following query.
SELECT P.NAME, S.NAME As SpouseName
FROM PEOPLE P
LEFT JOIN PEOPLE S ON P.Spouse = S.Spouse -- You should have a PK/FK relasionship here (SouseId) and not join on a name string
WHERE P.IsPrimary = 1
a way to do it like that
SELECT `Name`, `Spouse`
FROM Table1
WHERE `Name` <= `Spouse`
demo

Delete partial duplicates from a MySQL table

I have a table that looks like this
Id FirstName
5 Adam
6 Bob
8 Bob
5 Carl
5 Dewie
8 Ernest
When two rows have the same Id, I'd like to keep only one of them. On this example, I would obtain
Id FirstName
5 Adam
6 Bob
8 Bob
Is there concise command to that? I was thinking of
SELECT * FROM Persons HAVING(COUNT(Id)=1)
or
SELECT DISTINCT(Id), FirstName FROM Persons
but my syntax isn't correct.
Hope you are looking for this::
SELECT * from Persons GROUP BY Id
SELECT Id, MIN(FirstName)
FROM Persons
GROUP By Id
Your DISTINCT query will also work, you just need to add GROUP BY id
SELECT DISTINCT(Id), FirstName
FROM Persons
GROUP BY id;
Demo