mysql left join duplicates - mysql

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.

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

SQL search in relations

I have a main table with two relations.
Data structure and example:
A/Employee
id fields
1 Mike Miller
2 Lisa Miller
B/Skill
aid name
1 SQL
1 PHP
C/Language
aid name
1 German
I need a query which shows results from the main table and searches for a keyword in the relation tables.
Search for Miller -> Mike Miller, Lisa Miller
Search for SQL -> Mike Miller
Search for German -> Mike Miller
There are 10.000 rows in the main table and 100.000 relations.
I tried it with JOIN but the query is really slow.
Also the same row from the main table is displayed a view several times when there are more than one relations for this row:
Search for Miller
Returns: Mike Miller, Mike Miller
(Mike Miller displayed more than one time)
SELECT fields
FROM A
JOIN B ON id = B.aid JOIN C ON id = C.aid
WHERE fields LIKE '%"+$search+"%' OR B.name LIKE '%"+$search+"%' OR C.name LIKE '%"+$search+"%'"
I tried to fix the second problem with DISTINCT but now rows without relations are not displayed.
I want to display every row from the main table exactly one time. Which query do I need?
The problem with your first query, as you mention yourself, is that you get several duplicate rows returned. Not strange, since I guess the relation between table A and table B & C is one-to-many.
In your next attempt you added DISTINCT, and that will indeed get rid off the duplicates, but the regular join (or inner join) will only return matches where data can be joined, i.e. where data exists in both joined tables.
Introducing LEFT JOIN:
SELECT DISTINCT fields
FROM A
LEFT JOIN B ON id = B.aid
LEFT JOIN C ON id = C.aid
WHERE fields LIKE '%"+$search+"%' OR B.name LIKE '%"+$search+"%' OR C.name LIKE '%"+$search+"%'"
This will always search all data from table A, and those from table B & C where joins can be made. The DISTINCT will make sure that only unique rows are returned. You could also use GROUP BY for the same result, but that's usually used for aggregate methods.
Use LEFT JOIN.
Example:
SELECT distinct e.empname FROM Employee e
LEFT JOIN skill s ON s.aid = e.id
LEFT JOIN lang l ON l.aid = e.id
WHERE e.empname LIKE '%Miller%' OR s.name LIKE '%Miller%' OR l.name LIKE '%Miller%'
Proof SQL Fiddle

Display the number of entries in one table, for a key shared by two tables in SQL while also including entries with no place in the other

I'm very new to MySQL, so still learning. Basically, what I currently have is two tables:
Table 1, people, has a name, date of birth, and phone number.
Table 2, meetings, has a name, meeting date, and meeting time.
The entries in "name" in both tables are the same (although the names are mentioned multiple times), although Table 1 has an extra name, Paul, who has no meetings scheduled (so there are no entries of that person in Table 2).
I want to print out a simple, 2 column result showing:
name | number of meetings
david | 3
john | 4
jerry | 5
paul | 0
I am able to print out:
david | 3
john | 4
jerry | 5
using
SELECT name, COUNT(*) as Number_Of_Meetings FROM meetings GROUP BY name;
although this only really uses the name data in meetings so isn't really going to be helpful when trying to print out paul as well because he isn't included.
Using the people table I can also do the much more complicated
SELECT p.name, COUNT(*) as Number_of_Meetings FROM meetings m JOIN people p ON p.name = m.name GROUP BY p.name;
This instead shows the name entries in people but only the ones with an entry in meetings, but I cannot for the life of me figure out how to also show
paul | 0
I've tried so many options but honestly cannot figure it out.
Can somebody help please?
Since you want all records from the people table event when there aren't any matching records in meetings you'll want to use a left join:
SELECT p.name, COUNT(m.name) as Number_of_Meetings
FROM people p
LEFT JOIN meetings m ON p.name = m.name
GROUP BY p.name;

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)

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