Joining 3 tables in Sqlite and not receiving expected output - sql

I understand similar question have been posted, however my issue isn't an error rather the lack of the desired result. I'm trying to join 3 tables each with 10,000 observations and combine them in the one table, however when i use inner join the observations reduce to little over 4000. I understand that INNER JOIN is essentially an intersection but I'm expecting 10,000 observations and based on my code I don't see how that is occurring. Here is my code:
SELECT *
FROM Characteristics
INNER JOIN Prices ON Prices.pid = Characteristics.pid
INNER JOIN Locations ON Locations.tid = Characteristics.tid
;
CHARACTERISTICS
||Property_Id|| ||Beds|| ||Baths|| ||Type_ID||
PRICES
||Price|| ||Year|| ||Property_ID||
LOCATIONS
||Type_ID|| ||X coord|| ||Y coord||
Those are representative of the tables I didn't include numbers because of formatting issues but as you can imagine the number contained in Property_id and Type_id are the same for all columns regardless of table, what i would like is one table with each of the respective columns containing 10,000 rows, i've checked for NA values on R and they're all of the same length.

If you want to keep all characteristics -- even when there are no matches in the other tables -- then use left join:
SELECT *
FROM Characteristics c LEFT JOIN
Prices p
ON p.pid = c.pid LEFT JOIN
Locations l
ON l.tid = c.tid;

Related

Getting repeats of output, possibly doing a join wrong?

I'm having an issue where I'm getting some incorrect values in my output. I am binding the below highlighted table column with the circled column down the bottom. The service_id on the highlighted column is what is unique, but I need to bind the booking_id to retrieve the info (if that makes sense. What I end up getting is the top table where I get repeats, or the price is wrong. I should be getting only 5 lines in the top table.
Here's my code. I suspect I might be doing the join wrong?
SELECT bad.agent as Agents,
dog.SUPPLIER as SUPPLIER,
bad.status as TheStatus,
country.analysis_master1 as Country,
ftb.booking_actual_retail as BookingActualRetail,
ftb.Booking_Actual_Cost as BookingCost,
ftb.Booking_Actual_Retail_inc as BookingRetailINC,
fts.Service_Id,
fts.Service_Actual_Retail_inc as ServiceActualCostInc,
Product.SERVICE,
Product.SL_STATUS as SLSTATUS,
cat.name as Product2,
bad.LAST_SERVICE_DATE as Servicedate,
bad.LW_DATE as LWDATE,
ftb.Entered_Date as DATEENTERED,
ftb.Booking_Pax as PEOPLE,
ftb.Booking_Children as KIDS,
bad.TRAVELDATE as TRAVELDATE,
bad.FULL_REFERENCE
from BHD bad
inner join FTB on bad.FULL_REFERENCE = ftb.booking_reference
inner join FTS on FTB.Booking_Id = fts.Booking_Id
inner join DRM Country on bad.agent = country.code
inner join BSL Product on bad.BHD_ID = Product.BHD_ID
inner join SRV cat on Product.SERVICE = cat.CODE
inner join OPT dog on Product.OPT_ID = dog.OPT_ID
where bad.STATUS = 'IV' AND bad.FULL_REFERENCE = 'LTIT129488'
UPDATE:
Ok, so it looks like this join here causes the multiple outputs:
inner join FTS on FTB.Booking_Id = fts.Booking_Id
I have included the two tables, their headers, and sample data
You have somewhere put the join for the service or supplier in the wrong way.. Please check this line again.
inner join SRV cat on Product.SERVICE = cat.CODE
UPDATED SOLUTION :
As per your updated screenshots, I found the issue...
you have joined like this.
inner join FTB on bad.FULL_REFERENCE = ftb.booking_reference
In this join, your one table has single record against booking reference while another have multiple records against booking refrence. Thats why you are getting the multiple records in the output.
Remove this join and your problem will be solved. If you really want the data from this table then you can select in other way like using outer apply etc.

how to do complex join on same column?

I am trying to create a table using complex join among multiple tables..
using LEFT OUTER JOIN will give following result
however, for all the rows where category is coming blank, i want to do an SELF JOIN on sellerid to get category filled

Derived column results

i'm an sql novice and have to Formulate an SQL query that lists all 5 columns from a QUALITY table and adds two more columns: ProductCode of the items produced in the batch, and a derived column BatchQuality that contains “Poor” if the batch is of poor quality (contains more than 1 defective item) and “Good” otherwise.
I'm pulling from 3 tables that I put in an oracle database: Production table(contains serialno, batchno, and productcode), Quality table (batchno, test1, test2, teste3, test4), and defective table (defectiveid, serialno).
I'm able to get 6 out of 7 columns by using the following:
select q.batchno, q.test1, q.test2, q.test3, q.test4, p.productcode_id
from production p, defective d, quality q
where d.serialno = p.serialno
and p.batchno = q.batchno;
Any ideas on how to get the last column called batchquality that says if it's good or poor? I'm thinking that I need a count function, but once I have that, how would I go about getting a new column that would state poor or good?
Appreciate any help that can be provided.
Your current query is an inner join using an old, outdated implicit join in the where clause. I assume the defective table only contains a row for a product if there was a defect. Your inner join will always return defective parts only, never parts without defects. For that you need an outer join. Another reason to ditch the outdated implicit joins and use an explicit JOIN operator:
select q.batchno, q.test1, q.test2, q.test3, q.test4, p.productcode_id
from production p
JOIN quality q ON p.batchno = q.batchno;
LEFT JOIN defective d ON d.serialno = p.serialno
For products that do not have defects, the values for the columns from the defective table will be null. So to get a flag if a product had is "good" or "bad" you need to check if the value is null:
select q.batchno, q.test1, q.test2, q.test3, q.test4, p.productcode_id,
case
when d.serialno is null then 'good'
else 'bad'
as batch_quality
from production p
JOIN quality q ON p.batchno = q.batchno;
LEFT JOIN defective d ON d.serialno = p.serialno
Due to the nature of joins, the above statement will however repeat each row from the production table for each row in the quality and defective table. It is not clear to me if you want that or not.

Inner join sql statement

I have two tables, Invoices and members, connected by PK/FK relationship through the field InvoiceNum. I have created the following sql and it works fine, and pulls 44 records as expected.
SELECT
INVOICES.InvoiceNum,
INVOICES.GroupNum,
INVOICES.DivisionNum,
INVOICES.DateBillFrom,
INVOICES.DateBillTo
FROM INVOICES
INNER JOIN MEMBERS ON INVOICES.InvoiceNum = MEMBERS.InvoiceNum
WHERE MEMBERS.MemberNum = '20032526000'
Now, I want to replace INVOICES.GroupNum and INVOICES.DivisionNum in the above query with GroupName and DivisionName. These values are present in the Groups and Divisions tables which also have the corresponding Group_num and Division_num fields. I have created the following sql. The problem is that it now pulls 528 records instead of 44!
SELECT
INVOICES.InvoiceNum,
INVOICES.DateBillFrom,
INVOICES.DateBillTo,
DIVISIONS.DIVISION_NAME,
GROUPS.GROUP_NAME
FROM INVOICES
INNER JOIN MEMBERS ON INVOICES.InvoiceNum = MEMBERS.InvoiceNum
INNER JOIN GROUPS ON INVOICES.GroupNum = GROUPS.Group_Num
INNER JOIN DIVISIONS ON INVOICES.DivisionNum = DIVISIONS.Division_Num
WHERE MEMBERS.MemberNum = '20032526000'
Any help is greatly appreciated.
You have at least one relation between your tables which is missing in your query. It gives you extra records. Find all common fields. Say, are divisions related to groups?
The statement is fine, as far as the SQL syntax goes.
But the question you have to ask yourself (and answer it):
How many rows in Groups do you get for that given GroupNum?
Ditto for Divisions - how many rows exist for that DivisionNum?
It would appear that those numbers aren't unique - multiple rows exist for each number - therefore you get multiple rows returned

How to combine two tables, one with 1 row and one with n rows?

I have a database with two tables
One with games
and one with participants
A game is able to have more participants and these are in a different table.
Is there a way to combine these two into one query?
Thanks
You can combine them using the JOIN operator.
Something like
SELECT *
FROM games g
INNER JOIN participants p ON p.gameid = g.gameid
Explanation on JOIN operators
INNER JOIN - Match rows between the two tables specified in the INNER
JOIN statement based on one or more
columns having matching data.
Preferably the join is based on
referential integrity enforcing the
relationship between the tables to
ensure data integrity.
o Just to add a little commentary to the basic definitions
above, in general the INNER JOIN
option is considered to be the most
common join needed in applications
and/or queries. Although that is the
case in some environments, it is
really dependent on the database
design, referential integrity and data
needed for the application. As such,
please take the time to understand the
data being requested then select the
proper join option.
o Although most join logic is based on matching values between
the two columns specified, it is
possible to also include logic using
greater than, less than, not equals,
etc.
LEFT OUTER JOIN - Based on the two tables specified in the join
clause, all data is returned from the
left table. On the right table, the
matching data is returned in addition
to NULL values where a record exists
in the left table, but not in the
right table.
o Another item to keep in mind is that the LEFT and RIGHT OUTER
JOIN logic is opposite of one another.
So you can change either the order of
the tables in the specific join
statement or change the JOIN from left
to right or vice versa and get the
same results.
RIGHT OUTER JOIN - Based on the two tables specified in the join
clause, all data is returned from the
right table. On the left table, the
matching data is returned in addition
to NULL values where a record exists
in the right table but not in the left
table.
Self -Join - In this circumstance, the same table is
specified twice with two different
aliases in order to match the data
within the same table.
CROSS JOIN - Based on the two tables specified in the join clause, a
Cartesian product is created if a
WHERE clause does filter the rows.
The size of the Cartesian product is
based on multiplying the number of
rows from the left table by the number
of rows in the right table. Please
heed caution when using a CROSS JOIN.
FULL JOIN - Based on the two tables specified in the join clause,
all data is returned from both tables
regardless of matching data.
example
table Game has columns (gameName, gameID)
table Participant has columns (participantID, participantName, gameID)
the GameID column is the "link" between the 2 tables. you need a common column you can join between 2 tables.
SELECT gameName, participantName
FROM Game g
JOIN Participat p ON g.gameID = p.gameID
This will return a data set of all games and the participants for those games.
The list of games will be redundant unless you structure it some other way due to multiple participants to that game.
sample data
WOW Bob
WOW Jake
StarCraft2 Neal
Warcraft3 James
Warcraft3 Rich
Diablo Chris