MySQL Join with many (fields) to one (secondary table) relationship - mysql

I have a query I need to perform on a table that is roughly 1M records. I am trying to reduce the churn, but unfortunately there is a UNION involved (after i figure this join out), so that may be a question for another day.
The records and data I need to get reference 3 fields in a table that need each pull a description from another table and return it in the same record, but when i do the Inner join i was thinking, it either returns only 1 field fromt he other table, or multiple records from he original table.
Here are some screen shots of the tables and their relationship:
Primary table containing records (1 each) with the physician record I want to pull, including up to 3 codes that can be listed in the "taxonomy" table.
Secondary table containing records (1 each) with the "Practice" field I want to pull.
A Quick glance of the relationship i'm talking about
I presume that if perform an inner join matching the 3 fields in the physicians table, that it will have to iterate that table multiple times to pull each taxonomy code .. but I still can't even figure the syntax to easily pull all of these codes instead of just 1 of them.
i've tried this:
SELECT
taxonomy_codes.specialization,
physicians.provider_last_name,
physicians.provider_first_name,
physicians.provider_dba_name,
physicians.legal_biz_name,
physicians.biz_practice_city
FROM
taxonomy_codes
INNER JOIN physicians ON physicians.provider_taxonomy_code_1 = taxonomy_codes.taxonomy_codes OR physicians.provider_taxonomy_code_2 = taxonomy_codes.taxonomy_codes OR physicians.provider_taxonomy_code_3 = taxonomy_codes.taxonomy_codes
First, the query churns a lot and it only returns one taxonomy specialty result which I presume is because of the OR in the join statement. Any help would be greatly appreciated.
Thank you,
Silver Tiger

You have to join the taxonomy_codes table multiple times:
SELECT p.provider_last_name, p...., t1.specialization as specialization1, t2.specialization as specialization2, t3.specialization as specialization3
FROM physicians p
LEFT JOIN taxonomy_codes t1 ON t1.taxonomy_codes = provider_taxonomy_code_1
LEFT JOIN taxonomy_codes t2 ON t2.taxonomy_codes = provider_taxonomy_code_2
LEFT JOIN taxonomy_codes t3 ON t3.taxonomy_codes = provider_taxonomy_code_3

Related

SQL JOIN Query's to collect data for two columns

One of my tables has a column named "t_name" which supplies an exact name (ie: Google)
And another table has two columns named
m_team_home and m_team_away
Both m_team_home and m_team_away would be INT's in the database but would grab the name from the first table. My joined query is only able to grab the home's team name, and I don't know how to get the away team's name because it will output the same thing.
I know it may be hard to explain, but much help would be appreciated.
sounds like you want to join on the table twice
SELECT a.team, a1.team
FROM table t
JOIN another_table a on a.m_team_home = t.id -- t.id or whatever is in that table that maps to the home / away teams
JOIN another_table a1 on a1.m_team_away = t.id
that way you can get the name for the home team and away team.. you may want to consider making those LEFT joins just incase one doesn't exist and it gets filtered out

MySQL SELECT from two tables with COUNT

i have two tables as below:
Table 1 "customer" with fields "Cust_id", "first_name", "last_name" (10 customers)
Table 2 "cust_order" with fields "order_id", "cust_id", (26 orders)
I need to display "Cust_id" "first_name" "last_name" "order_id"
to where i need count of order_id group by cust_id like list total number of orders placed by each customer.
I am running below query, however, it is counting all the 26 orders and applying that 26 orders to each of the customer.
SELECT COUNT(order_id), cus.cust_id, cus.first_name, cus.last_name
FROM cust_order, customer cus
GROUP BY cust_id;
Could you please suggest/advice what is wrong in the query?
You issue here is that you have told the database how these two tables are 'connected', or what they should be connected by:
Have a look at this image:
~IMAGE SOURCE
This effectively allows you to 'join' two tables together, and use a query between them.
so you might want to use something like:
SELECT COUNT(B.order_id), A.cust_id, A.first_name, A.last_name
FROM customer A
LEFT JOIN cust_order B //this is using a left join, but an inner may be appropriate also
ON (A.cust_id= B.Cust_id) //what links them together
GROUP BY A.cust_id; // the group by clause
As per your comment requesting some further info:
Left Join (right joins are almost identical, only the other way around):
The SQL LEFT JOIN returns all rows from the left table, even if there are no matches in the right table. This means that if the ON clause matches 0 (zero) records in right table, the join will still return a row in the result, but with NULL in each column from right table. ~Tutorials Point.
This means that a left join returns all the values from the left table, plus matched values from the right table or NULL in case of no matching join predicate.
LEFT joins will be used in the cases where you wish to retrieve all the data from the table in the left hand side, and only data from the right that match.
Execution Time
While the accepted answer in this case may work well in small datasets, it may however become 'heavy' in larger databases. This is because it was not actually designed for this type of operation.
This was the purpose of Joins to be introduced.
Much work in database-systems has aimed at efficient implementation of joins, because relational systems commonly call for joins, yet face difficulties in optimising their efficient execution. The problem arises because inner joins operate both commutatively and associatively. ~Wikipedia
In practice, this means that the user merely supplies the list of tables for joining and the join conditions to use, and the database system has the task of determining the most efficient way to perform the operation. A query optimizer determines how to execute a query containing joins. So, by allowing the dbms to choose the way your data is queried, you can save a lot of time.
Other Joins/Summary
AN INNER JOIN will return data from both tables where the keys in each table match
A LEFT JOIN or RIGHT JOIN will return all the rows from one table and matching data from the other table.
Use a join when you want to query multiple tables.
Joins are much faster than other ways of querying >=2 tables (speed can be seen much better on larger datasets).
You could try this one:
SELECT COUNT(cus_order.order_id), cus.cust_id, cus.first_name, cus.last_name
FROM cust_order cus_order, customer cus
WHERE cus_order.cust_id = cus.cust_id
GROUP BY cust_id;
Maybe an left join will help you
SELECT COUNT(order_id), cus.cust_id, cus.first_name, cus.last_name ]
FROM customer cus
LEFT JOIN cust_order co
ON (co.cust_id= cus.Cust_id )
GROUP BY cus.cust_id;

SQL - Joining tables BUT not always

I need to perform a query SELECT that joins three tables (no problem with that). Nonetheless, the third table can, or NOT, have any element that match the joining KEY.
I want ALL data from the first two tables and if the ITEMS have ALSO information in the third table, fetch this data to.
For example, imagine that the first table have a person, the second table have his/her address (everyone lives anywhere), the third table stores the driving license (not everyone has this) - but I need to fetch all data whether or not people (all people) have driving license.
Thanks a lot for reading, if possible to give you suggestion / solution!
Use LEFT JOIN to join the third table. Using INNER JOIN a row has to exists. Using LEFT JOIN, the 'gaps' will be filled with NULLs.
SELECT
p.PersonID, -- NOT NULL
-- dl.PersonID, -- Can be null. Don't use this one.
p.FirstName,
p.LastName,
a.City,
a.Street,
dl.ValidUntilDate
FROM
Person p
INNER JOIN Addresse a ON a.AddressID = p.HomeAddressID
LEFT JOIN DrivingLicence dl ON dl.PersonId = p.PersonID

MySQL one to many data relationship with added complications

I have a database in which there are multiple posts. Each post can be associated with one or more location. Each location is then associated with one country.
This is handled through four tables:
post (with the id and post_title)
postlocation (with the fields post_id and location_id - to allow a one to many relationship)
location (with the fields id, location_title and country_id)
country (with the fields, id and country_title)
I want to perform a simple, effective select to retrieve a list of posts and each one's associated locations and each of those locations' country.
I'm at a loss as to how to best achieve this, and any help would be most welcome. Thank you.
Use LEFT JOIN:
SELECT post.*, location.*, country.*
FROM post
LEFT JOIN postlocation ON post.id = postlocation.post_id
LEFT JOIN location ON postlocation.location_id = location.id
LEFT JOIN country ON location.country_id = country.id
Here's an explanation of how LEFT JOIN works: http://www.mysqltutorial.org/mysql-left-join.aspx
The MySQL LEFT JOIN clause works like this: when a row from the left
table matches a row from the right table based on join_condition, the
row’s content are selected as an output row. When row in the left
table has no match it is still selected for output, but combined with
a “fake” row from the right table that contains NULL in all columns.
In short, the MySQL LEFT JOIN clause allows you to select all rows
from the left table even there is no match for them in the right
table.
When you have multiple LEFT JOINs, then in each case it uses the cumulative results so far as the "left" table and the table your are joining on as the "right" table.
So the query above will return one row for every post/location/country. Note that this means there will be potentially several rows with the same post.* data (one for each postlocation associated with taht post).
And if a post has no postlocations associated with it, that post will still show up in the results (but with null rows for location.* and country.*). Similarly, if a location has no country associated it with it, the post/location rows will still show up in the output (but with null rows for country.*). This is the advantage of LEFT JOIN -- you always get all the rows from the table on the "left".

INTERSECT 2 tables in MySQL

I need to intersect two tables based
on a column,in both tables.
Here's my code snippet :
SELECT b.VisitID, b.CarrierName, b.PhoneNum, b.PatientName, b.SubscriberID, b.SubscriberName,
b.ChartNum, b.DoB, b.SubscriberEmp, b.ServiceDate, b.ProviderName, b.CPTCode, b.AgingDate,
b.BalanceAmt, f.FollowUpNote, f.InternalStatusCode FROM billing b JOIN followup f
USING (VisitID) WHERE b.VisitID = f.VisitID
In the 'followup' table I've 281 rows AND 'billing' table contains 2098 rows. When I execute this query I'm getting 481 rows.
Did anyone faces this sort of problem?
Could you help me to INTERSECT these tables?
Thanx in advance..
I think you like to do a left join here (not an inner join as in your example):
SELECT b.VisitID, b.CarrierName, b.PhoneNum, b.PatientName,
b.SubscriberID, b.SubscriberName, b.ChartNum, b.DoB,
b.SubscriberEmp, b.ServiceDate, b.ProviderName, b.CPTCode,
b.AgingDate, b.BalanceAmt,
f.FollowUpNote, f.InternalStatusCode
FROM billing b
LEFT JOIN followup f ON b.VisitID = f.VisitID
This will also return rows from the 'billing' table that don't have corresponding fields in the 'followup' table.
It seems to me that you'd be very likely to have multiple follow ups. Thus the 481 records from the notes table is likely accurate.
Perhaps add an
ORDER BY b.SubscriberID
to JochenJung's answer above and accept that you have the right number of rows.
alternately a
GROUP BY b.SubscriberID
Would give you one row per customer