mysql - combining 2 tables with different condition - mysql

Here i have 2 tables user and userStore
user Table
╔════╦══════╦════════╦═══════════╗
║ ID ║ NAME ║ ROLE ║ STORECODE ║
╠════╬══════╬════════╬═══════════╣
║ 1 ║ A ║ Admin ║ ║
║ 2 ║ B ║ Store ║ 1 ║
║ 3 ║ C ║ Store ║ ║
║ 4 ║ D ║ Client ║ ║
║ 5 ║ E ║ Staff ║ ║
╚════╩══════╩════════╩═══════════╝
userStore Table
╔════╦══════════╗
║ ID ║ CATEGORY ║
╠════╬══════════╣
║ 1 ║ X ║
║ 2 ║ X ║
╚════╩══════════╝
Output
╔════╦══════╦════════╦═══════════╦══════════╗
║ ID ║ NAME ║ ROLE ║ STORECODE ║ CATEGORY ║
╠════╬══════╬════════╬═══════════╬══════════╣
║ 1 ║ A ║ Admin ║ ║ ║
║ 2 ║ B ║ Store ║ 1 ║ X ║
║ 4 ║ D ║ Client ║ ║ ║
║ 5 ║ E ║ Staff ║ ║ ║
╚════╩══════╩════════╩═══════════╩══════════╝
I want to fetch all the rows from user table with the role other than store. And wanted to include the store role only if it have match in the userstore table.
In the output you can see that the id=3 is not available since it doesn't have match from user store.

This should be straight forward, use LEFT JOIN
SELECT a.*, b.*
FROM user a
LEFT JOIN userStore b
ON a.StoreCode = b.ID
WHERE (a.role <> 'Store') OR
(a.role = 'Store' AND NOT b.ID IS NULL )
SQLFiddle Demo
Other Source
Visual Representation of Join

Try this:
SELECT u.id, u.name, u.role, u.StoreCode, IFNULL(us.id, '') id, IFNULL(us.Category, '') Category
FROM USER u
LEFT JOIN userStore us ON u.StoreCode = us.id
WHERE IF(LOWER(u.role) = 'store', u.StoreCode IS NOT NULL AND u.StoreCode != '', TRUE);

Related

Select all customers and all orders with single query

Is there a way with single mysql query to output all customers and all their orders including customers without orders? I have:
Customers:
╔════╦═════════════╗
║ ID ║ NAME ║
╠════╬═════════════╣
║ 1 ║ John Smith ║
║ 2 ║ Jim Jimmers ║
╚════╩═════════════╝
Orders:
╔═══════╦══════════╦═══════╗
║ id ║ ClientID ║ Status║
╠═══════╬══════════╬═══════╣
║ 1 ║ 1 ║ wait ║
║ 2 ║ 1 ║ rdy ║
╚═══════╩══════════╩═══════╝
How do I select a result like:
╔════╦═════════════╦═════════════╦═════════════╗
║ ID ║ NAME ║ Order Id ║ Order Status║
╠════╬═════════════╬═════════════╬═════════════╣
║ 1 ║ John Smith ║ 1 ║ wait ║
║ 1 ║ John Smith ║ 2 ║ rdy ║
║ 2 ║ Jim Jimmers ║ ║ ║
╚════╩═════════════╩═════════════╩═════════════╝
Just use a left join between the two tables:
SELECT c.ID, c.NAME, o.id AS OrderId, o.Status AS OrderStatus
FROM Customers c
LEFT JOIN Orders o
ON o.ClientID = c.ID
ORDER BY c.ID, o.id;

using condition for Group_Concat

I want to find all ids of which group_concat only contains 'a'.
Here is simplified table from mine.
╔════╦══════════════╦
║ id ║ group_concat ║
╠════╬══════════════╬
║ 1 ║ a,b,b ║
║ 2 ║ a ║
║ 3 ║ a,a ║
║ 4 ║ a,a,a ║
║ 5 ║ a,b,a ║
╚════╩══════════════╩
And the table below is what I want to achieve.
╔════╦══════════════╦
║ id ║ group_concat ║
╠════╬══════════════╬
║ 2 ║ a ║
║ 3 ║ a,a ║
║ 4 ║ a,a,a ║
╚════╩══════════════╩
And this is the query statement I am trying to use.
select id, group_concat(val)
from user
group by id
having group_concat(val) = 'a'
Thanks in advance
Try this:
select id, group_concat(val)
from user
group by id
having count(distinct val) = 1 and max(val) = 'a'

How to get corresponding id with minimum value of a row in MySQL?

I have two tables named deals and mp_details. Columns deal_id and mp_details_id are the two primary keys. There is a relation between the two tables using the deal_mp_id column where it works as a foreign key. I want to fetch all the minimum records of column name deal_selling_price with group by mp_details_id. Here are the tables:
deals
╔═════════╦════════════╦════════════════════╗
║ deal_id ║ deal_mp_id ║ deal_selling_price ║
╠═════════╬════════════╬════════════════════╣
║ 3 ║ 1 ║ 425 ║
║ 4 ║ 1 ║ 540 ║
║ 5 ║ 2 ║ 340 ║
║ 6 ║ 2 ║ 315 ║
║ 7 ║ 3 ║ 425 ║
║ 8 ║ 3 ║ 720 ║
║ 9 ║ 4 ║ 382.5 ║
║ 10 ║ 4 ║ 495 ║
║ 11 ║ 5 ║ 595 ║
║ 12 ║ 5 ║ 720 ║
╚═════════╩════════════╩════════════════════╝
mp_details
╔═══════════════╦═════════════════════╗
║ mp_details_id ║ mp_details_name ║
╠═══════════════╬═════════════════════╣
║ 1 ║ Olive Bar & Kitchen ║
║ 2 ║ Thai High ║
║ 3 ║ Tonino ║
║ 4 ║ Impromptu ║
║ 5 ║ Zerruco ║
╚═══════════════╩═════════════════════╝
And I want this kind of result:
╔═════════╦════════════╦════════════════════╗
║ deal_id ║ deal_mp_id ║ deal_selling_price ║
╠═════════╬════════════╬════════════════════╣
║ 3 ║ 1 ║ 425 ║
║ 6 ║ 2 ║ 315 ║
║ 7 ║ 3 ║ 425 ║
║ 9 ║ 4 ║ 382.5 ║
║ 11 ║ 5 ║ 595 ║
╚═════════╩════════════╩════════════════════╝
The following query will give you the result set from your screen capture above:
SELECT d1.deal_id, d1.deal_mp_id, d2.minPrice
FROM deals d1
INNER JOIN
(
SELECT deal_mp_id, MIN(deal_selling_price) AS minPrice
FROM deals
GROUP BY deal_mp_id
) d2
ON d1.deal_mp_id = d2.deal_mp_id AND d1.deal_selling_price = d2.minPrice
If you also want to include information from the mp_details table, you can do an additional join like this:
SELECT d1.deal_id, d1.deal_mp_id, d2.minPrice, mp.mp_details_name
FROM deals d1
INNER JOIN
(
SELECT deal_mp_id, MIN(deal_selling_price) AS minPrice
FROM deals
GROUP BY deal_mp_id
) d2
ON d1.deal_mp_id = d2.deal_mp_id AND d1.deal_selling_price = d2.minPrice
INNER JOIN mp_details mp
ON d1.deal_mp_id = mp.mp_details_id
Follow the link below for a running demo:
SQLFiddle
Try below query
select
D.Deal_id, MD.mp_details_id, MIN(D.deal_selling_price)
FROM
deals D inner join mp_details MD
ON
D.Deal_id = MD.mp_details_id
GROUP BY
D.Deal_id, MD.mp_details_id
Use this query:
SELECT d.deal_id, d.deal_mp_id, d.deal_selling_price
FROM deals d
JOIN
(
SELECT deal_mp_id, MIN(deal_selling_price) AS min_selling_price
FROM deals
GROUP BY deal_mp_id
) m
ON d.deal_mp_id = m.deal_mp_id AND d.deal_selling_price = m.min_selling_price

MySQL LEFT JOIN multiple rows from TableB

The tables below are an example table structure.
The query I am trying to write is something like:
SELECT * FROM jobs LEFT JOIN assigned ON jobs.id = assigned.job_id;
However, as you can see the left join will product multiple matches in the case of job 100, but the above query will only return one match.
Is it possible to concatenate the results into a comma separated string for the left join?
If possible, a step further would be, is it possible to replace the assigned.user_id with the users.name column in the concatenated comma separated string.
users
╔═══╦════════════╦═════════════╗
║ ║ id ║ name ║
╠═══╬════════════╬═════════════╣
║ 1 ║ 1 ║ Matt ║
║ 2 ║ 2 ║ Phil ║
║ 3 ║ 3 ║ Chris ║
╚═══╩════════════╩═════════════╝
jobs
╔═══╦════════════╦═════════════╗
║ ║ id ║ name ║
╠═══╬════════════╬═════════════╣
║ 1 ║ 100 ║ Do this ║
║ 2 ║ 101 ║ Do that ║
║ 3 ║ 102 ║ And this ║
╚═══╩════════════╩═════════════╝
assigned
╔═══╦════════════╦═════════════╗
║ ║ user_id ║ job_id ║
╠═══╬════════════╬═════════════╣
║ 1 ║ 1 ║ 100 ║
║ 2 ║ 2 ║ 100 ║
║ 3 ║ 1 ║ 101 ║
╚═══╩════════════╩═════════════╝
SELECT jobs.id,
jobs.name,
GROUP_CONCAT( users.name order by users.name) as workersOnTheJob
FROM
jobs
LEFT JOIN assigned
ON jobs.id = assigned.job_id
LEFT JOIN users
on assigned.user_id = users.id
group by
jobs.id,
jobs.name

Need help to retrieve data from three MySQL tables

I have three tables named "users","user_hobbies" and "hobbies". Below is the sample tables with values;Below is the users table with fields id, name and age
╔════╦══════╦═════╗
║ ID ║ NAME ║ AGE ║
╠════╬══════╬═════╣
║ 1 ║ abc ║ 23 ║
║ 2 ║ xyz ║ 24 ║
║ 3 ║ pqr ║ 21 ║
╚════╩══════╩═════╝
and below is user_hobbies table with fields id, user_id and hobby_id
╔════╦═════════╦══════════╗
║ ID ║ USER_ID ║ HOBBY_ID ║
╠════╬═════════╬══════════╣
║ 1 ║ 1 ║ 1 ║
║ 2 ║ 1 ║ 2 ║
║ 3 ║ 1 ║ 3 ║
║ 4 ║ 2 ║ 4 ║
║ 5 ║ 2 ║ 3 ║
║ 6 ║ 2 ║ 5 ║
║ 7 ║ 3 ║ 2 ║
║ 8 ║ 4 ║ 6 ║
╚════╩═════════╩══════════╝
. Below is the hobbies table with fields id and desc
╔════╦═══════════╗
║ ID ║ DESC ║
╠════╬═══════════╣
║ 1 ║ music ║
║ 2 ║ chatting ║
║ 3 ║ cricket ║
║ 4 ║ badminton ║
║ 5 ║ chess ║
║ 6 ║ cooking ║
╚════╩═══════════╝
. The actual requirement is that i need a query to retrieve name, age, hobby_id and desc (see an example below)
╔══════╦═════╦══════════╦═════════════════════════╗
║ NAME ║ AGE ║ HOBBYID ║ DESC ║
╠══════╬═════╬══════════╬═════════════════════════╣
║ abc ║ 23 ║ 1,2,3 ║ music,chatting,cricket ║
║ pqr ║ 21 ║ 2 ║ chatting ║
║ xyz ║ 24 ║ 4,3,5 ║ badminton,cricket,chess ║
╚══════╩═════╩══════════╩═════════════════════════╝
You need to join the tables first and use an aggregate function called GROUP_CONCAT().
SELECT a.Name,
a.Age,
GROUP_CONCAT(c.ID) hobbyIDs,
GROUP_CONCAT(c.desc) descList
FROM users a
INNER JOIN user_hobbies b
ON a.ID = b.user_ID
INNER JOIN hobbies c
ON b.hobby_ID = c.ID
GROUP BY a.Name, a.Age
SQLFiddle Demo
MySQL GROUP_CONCAT()
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
OUTPUT
╔══════╦═════╦══════════╦═════════════════════════╗
║ NAME ║ AGE ║ HOBBYIDS ║ DESCLIST ║
╠══════╬═════╬══════════╬═════════════════════════╣
║ abc ║ 23 ║ 1,2,3 ║ music,chatting,cricket ║
║ pqr ║ 21 ║ 2 ║ chatting ║
║ xyz ║ 24 ║ 4,3,5 ║ badminton,cricket,chess ║
╚══════╩═════╩══════════╩═════════════════════════╝