Proper formatting for this MYSQL query required - mysql

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

Related

Display all results of SQL query (including where count 0)

I have the following Query:
SELECT airportname, COUNT(DISTINCT foundBag.id) countFound, COUNT(DISTINCT lostBag.id) countLost
FROM airports
INNER JOIN foundBag ON airport_id = foundBag.airportDest
INNER JOIN lostBag ON airport_id = lostBag.airportDest
GROUP BY airport.airportname");
What I have now: A table that has 3 columns: Airport name with the number of bags found and number of bags lost.
It only displays an airport (row) when both of the columns are filled.
I want 2 things:
To display all the airports even when there are no lost / found bags.
To display the airports where the are lost / found bags (so when 1 or both the columns are filled)
I tried this with When etc. but it keeps giving me errors. I also tried the EXISTS but I'm new to SQL so I do not know how it works...
Does someone have a solution?
Kind regards,
LTKort
This should work for both conditions:
SELECT airportname, COUNT(DISTINCT foundBag.id) countFound, COUNT(DISTINCT lostBag.id) countLost
FROM airports
LEFT JOIN foundBag ON airport_id = foundBag.airportDest
LEFT JOIN lostBag ON airport_id = lostBag.airportDest
WHERE foundBag.airportDest is not null
or lostBag.airportDest is not null
GROUP BY airport.airportname

MySQL Multiple tables JOIN , same column title

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

MySQL, Show value of column if match exist else leave as null

I'm sure this has been asked before but can't find the answer.
I have 3 tables OWNER, CAR, HOUSE
OWNER has 2 columns id and name
CAR has 3 columns id, ownerId and cartype
HOUSE has 4 columns id, ownerId, address, country
I want to write a SQL query that gets the owners name, cartypes, and addresses that are in Sweden
Here comes the tricky part. I want all the owners names and cartypes in the result table even if they don't own a house in Sweden. Can I get all that in 1 query or do I need to use 2? How would that query look?
You should be able to accomplish this with a simple left join:
SELECT O.name, C.cartype, H.address, H.country
FROM OWNER AS O
JOIN CAR AS C ON O.id = C.ownerid
LEFT JOIN HOUSE AS H ON O.id = H.ownerid AND Ucase(H.country) = "SWEDEN"
This will always give you a list of owners and their car types, in addition, it will give you a list of those that also happen to have a house address in sweden.
First you need to join the table then add new column in query by using CASE to check
SELECT o.* , c.* ,h.*,
(CASE WHEN h.county ='sweden' THEN h.county ELSE NULL END) AS HasCountry
FROM OWNER o
JOIN CAR c ON (c.ownerId =o.id)
JOIN HOUSE h ON (h.ownerId =o.id)

mysql left join duplicates

ive been searching for hours but cant find a solution. its a bit complicated so i'll break it down into a very simple example
i have two tables; people and cars
people:
name_id firstname
1 john
2 tony
3 peter
4 henry
cars:
name_id car_name
1 vw gulf
1 ferrari
2 mustang
4 toyota
as can be seen, they are linked by name_id, and john has 2 cars, tony has 1, peter has 0 and henry has 1.
i simply want to do a single mysql search for who has a (1 or more) car. so the anwser should be john, tony, henry.
the people table is the master table, and im using LEFT JOIN to add the cars. my problem arises from the duplicates. the fact that the table im joining has 2 entries for 1 id in the master.
im playing around with DISTINCT and GROUP BY but i cant seem to get it to work.
any help is much appreciated.
EDIT: adding the query:
$query = "
SELECT profiles.*, invoices.paid, COUNT(*) as num
FROM profiles
LEFT JOIN invoices ON (profiles.id=invoices.profileid)
WHERE (profiles.id LIKE '%$id%')
GROUP BY invoices.profileid
";
try this
select distinct p.name_id, firstname
from people p, cars c
where p.name_id = c.name_id
or use joins
select distinct p.name_id, firstname
from people p
inner join cars c
on p.name_id = c.name_id
If you only want to show people that have a car, then you should use a RIGHT JOIN. This will stop any results from the left table (people) to be returned if they didn't have a match in the cars table.
Group by the persons name to remove duplicates.
SELECT firstname
FROM people P
RIGHT JOIN cars C ON C.name_id = P.name_id
GROUP BY firstname
SELECT DISTINCT firstname
FROM people
JOIN cars ON cars.name_id = people.name_id;
If this doesn't work you might have to show us the full problem.
The way to propose it there's no need for a left join since you need at least a car per person. Left join is implicitely an OUTER join and is intended to return the results with 0 corresponding records in the joinned table.

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