MySQL Multiple tables JOIN , same column title - mysql

I have a problem and I don't know how to solve it. I'm trying but still no success.
I have 3 tables:
tour
id_tour title
1 Discovery
2 Something
tour_to_country
id_tour id_country
1 66
1 35
1 673
2 88
2 91
country
id_country title
1 Country_1
2 Country_2
... ...
999 Country_999
I want to take the 2 tours from tour table, select all the countries inside each tour and display their name.
I want to select all the countries from each tour but the tour should be displayed once.
This is what I've tried:
SELECT tour.id_tour as tour_id, tour.title as tour_title, country.title as country_title, tour.* FROM tour
INNER JOIN tour_to_country ON tour.id_tour = tour_to_country.id_tour
INNER JOIN country ON country.id_country = tour_to_country.id_country
GROUP BY tour.id_tour
It gives me the tours but I still don't know how to take all the countries in the same query.

GROUP_CONCAT should do the trick for you. You can specify ordering and separator. I assume this is what you wanted to achieve.
SELECT tour.id_tour as tour_id, tour.title as tour_title, GROUP_CONCAT(country.title ORDER BY country.title SEPARATOR ',') as country_title, tour.* FROM tour
INNER JOIN tour_to_country ON tour.id_tour = tour_to_country.id_tour
INNER JOIN country ON country.id_country = tour_to_country.id_country
GROUP BY tour.id_tour

Related

Mysql Query with two seperate join

Does anyone know the solution to this problem ?
There are 3 Tables: orders, order_groups and stores.
I want to list the orders, with the names of the stores where the order was placed, and where the order is going to be delivered.
I keep the from_store_id, and to_store_id in the order_groups table
Listing these orders would be simple, i just left join the order_groups to orders, and select the name, from_shop_id and to_shop_id, but the problem is i want the name of the stores not the id, and the store names are placed in a different table (stores)
Here is what im talking about:
Table orders
id group_id name madeup_id
1 11 johnny cash 1
2 12 billy bob 1
LEFT JOIN order_groups on order_groups.id = orders.group_id
Table order_groups
id from_store_id to_store_id
11 55 56
12 56 55
Table stores
id store_name
55 thisstore
56 thatstore
The result im looking for is:
name from_store to_store
1.johhny cash thisstore, thatstore
2.billy bob thatstore, thisstore
The statement i have yet:
SELECT
orders.name, something as from_store, something as to_store
FROM orders
LEFT JOIN order_groups on order_groups.id = orders.group_id
somehow join stores on the order_groups.from_store_id = stores.id
WHERE orders.madeup_id = 1
Any idea how to select and join the store names to the query ?
One more question. I actually want to list two kind of orders in one query from different tables too, im on the right track with this structure ?
SELECT a,b FROM a LEFT JOIN b ON b.something=a.something WHERE something
UNION ALL
SELECT a,b FROM c LEFT JOIN c ON c.something=a.something WHERE something
You only need to join 2 times the same table!
SELECT
orders.name, fromStore.store_name as from_store, toStore.store_name as to_store
FROM orders
LEFT JOIN order_groups on order_groups.id = orders.group_id
left join stores fromStore on the order_groups.from_store_id = fromStore.id
left join stores toStore on the order_groups.to_store_id = toStore.id
WHERE orders.madeup_id = 1

MYSQL query for one to many relation

i have two tables:-
1- section
id name location_id
1 demo1 20
2 demo2 34
2- amenities
id amenity_id amenity_type object_id object_type
1 wedding_hall venue_type 1 section
2 conference_hall venue_type 1 section
3 conference_hall venue_type 2 section
i want all those section whose location_id is 134 and who has wedding_hall and conference hall both. I have tried this query:-
SELECT s.* from section s
INNER JOIN amenities am
on (am.object_type='section' AND am.object_id=s.id)
WHERE s.location_id=134 AND
(am.amenity_type LIKE 'venue_type' and am.amenity_id='wedding_hall')
AND (am.amenity_type LIKE 'venue_type' and am.amenity_id='conference_hall')
if i do this query:-
SELECT s.* from section s
INNER JOIN amenities am
on (am.object_type='section' AND am.object_id=s.id)
WHERE s.location_id=134 AND
(am.amenity_type LIKE 'venue_type' and am.amenity_id='wedding_hall')
then it works bot not for more than one amenity.
here is sqlfiddle
how can i correct my query?
I think you need subqueries for that. Maybe take a look at the EXISTS condition. The following will give you the desired result if the section has both wedding hall and conference hall (but not if you have just two wedding halls, and it's working with more than one section):
SELECT DISTINCT s.* FROM section s
INNER JOIN amenities a
ON a.object_id = s.location_id
WHERE s.location_id = 134
AND EXISTS(SELECT * FROM amenities WHERE object_id = s.location_id AND amenity_id = 'wedding_hall')
AND EXISTS(SELECT * FROM amenities WHERE object_id = s.location_id AND amenity_id = 'conference_hall');
Maybe add amenity_type and object_type conditions to the WHERE clauses.
If I did not mistake your question and you really want section which id = 1, try this:
SELECT s.*
FROM section s
INNER JOIN amenities am
ON am.object_type='section' AND am.object_id=s.id
WHERE s.location_id=134
AND am.amenity_type LIKE 'venue_type'
AND am.amenity_id IN ('wedding_hall', 'conference_hall')
-- HAVING COUNT(DISTINCT am.amenity_id) > 1
GROUP BY s.id
HAVING COUNT(DISTINCT am.amenity_id) = 2
SQLFiddle Demo

Using Where and Count on two tables

I have two tables
Foods
----------
ID Name
----------
1. Chips
2. Pizza
3. Fish
4. Pasta
People
-----------------
ID Name FoodID
-----------------
1. Robert 3
2. Norman 2
3. Leonard 4
4. Huey 3
What I'm supposed to do is retrieve any food that belongs to more than one person. Now I'm supposed to do this by means of COUNT and WHERE. Possibly might need to do an INNER JOIN.
It should be simple but I'm just not seeing it.
You want to join the tables on the common field. The WHERE is serving as an inner join. Then GROUP BY Foods.name aggregate rows by food type. Count is an aggregate operator that always works with the GROUP BY.
SELECT Foods.Name, Count(*)
FROM Foods, People
WHERE Foods.ID = People.Food
GROUP BY Foods.Name
HAVING COUNT(*)>1;
Omit the first count(*) if you just want the list of foods.
select f.name, p.name, count(f.id) as total from foods f, people p
where (f.id = p.FoodID)
group by f.name
having total > 1
order by f.name
http://sqlfiddle.com/#!9/b2a63/10
select * from food inner join people on people.id = food.id group by people.name

Grouping, counting and excluding based on column value

Although I've not a complete newbie in SQL or MySQL I notice that there's still quite a bit to learn. I cannot get my head around this one, after much trying, reading and searching. If you can give any pointers, I'd be grateful.
I have simplified the actual data and tables to the following.
Two tables are relevant: Staff, and Work. They contain data on staff in various projects.
Staff:
ID Name Unit
1 Smith Chicago
2 Clarke London
3 Hess Chicago
Work:
StaffID ProjectID
1 10
2 10
3 10
1 20
2 30
3 40
1 50
3 50
Goal:
To get grouped all those projects where there are staff from Chicago, with the count of all staff in that project.
Expected result:
Project Staff count
10 3
20 1
40 1
50 2
So the project 30 is not listed because its member(s) are not from Chicago.
My query below is obviously wrong. It counts only those project members who are from Chicago, not the whole project staff.
SELECT
work.projectID as Project, COUNT(*) as "Staff count"
FROM
staff
JOIN
work ON staff.ID=work.staffID
WHERE
unit="Chicago"
GROUP BY
work.projectID;
I'd put the test for Chicago in a subselect.
Alternatively you can use a self-join, but I find the sub-select easier to understand.
SELECT
w.projectid as project
,COUNT(*) as `staff count`
FROM work w
INNER JOIN staff s ON (w.staffID = s.id)
WHERE w.projectID IN (
SELECT w2.projectID FROM work w2
INNER JOIN staff s2 ON (w2.staffID = s2.id AND s2.unit = 'Chicago'))
GROUP BY w.projectid
Remove the where clause and add a having clause which checks that at least one member of staff is from Chicago.
SELECT
work.projectID as Project, COUNT(*) as "Staff count"
FROM
staff
JOIN
work ON staff.ID=work.staffID
GROUP BY
work.projectID
HAVING
count(case unit when 'Chicago' then 1 end) > 0;
Finally: the result. Thanks again both #Johan and #a'r for your help, and #Johan for getting me on the right track (in my case).
I changed the sub-select to a derived table, and inner-joined this with the Work table on projectID.
SELECT
w.projectID AS project
,COUNT(*) AS `staff count`
FROM work w
INNER JOIN
(SELECT DISTINCT w2.projectID
FROM work w2
INNER JOIN staff s ON (w2.staffID = s.id AND s.unit = 'Chicago')) c
ON (w.projectID = c.projectID)
GROUP BY w.projectID

Proper formatting for this MYSQL query required

Struggling to get the correct MYSQL query assembled to do the following:
2 Tables (Locations and Venues).
In Locations I want to get the Unique location_name and location_id Where there is a venue with on_website = 1
This is to draw a drop down list for navigation.
So I have London as a location and in London I have several venues
In Wilmslow I have a location but there are not venues that I want to advertise (on_website = 0 on those)
Currently I get the output
Bath
London
Birmingham
London
Bristol
London
Where I would want
Bath
London
Birmingham
Tried this:
SELECT
tblLocations.location_name,
tblLocations.location_id,
tblVenues.venue_id
FROM
tblLocations
INNER JOIN tblVenues ON (tblLocations.location_id = tblVenues.location_id)
Where tblVenues.on_website = 1
And tried using distinct but It still gives me duplicate locations.
Any help would be great thanks
SELECT DISTINCT
tblLocations.location_name,
tblLocations.location_id
FROM
tblLocations
INNER JOIN tblVenues ON (tblLocations.location_id = tblVenues.location_id)
Where tblVenues.on_website = 1
You have to use distinct without the venue_id, because the venue_id is different for different rows in your query. Distinct only filters exactly matching rows.
If you'd listed all three selected columns, you'd saw that each of them are unique. That's how DISTINCT works. Just do not select fields you don't need.
GROUP BY could do the trick
SELECT
tblLocations.location_name,
tblLocations.location_id,
tblVenues.venue_id
FROM
tblLocations
INNER JOIN tblVenues ON (tblLocations.location_id = tblVenues.location_id)
Where tblVenues.on_website = 1
GROUP BY tblLocations.location_id