SQL - Multiple criteria with a LEFT OUTER JOIN - sql

I am trying to do an OUTER JOIN, with multiple join conditions. Here is my query (I will explain issue below):
SELECT ad.*, cp.P_A, cp.P_B, cp.P_C
INTO #AggData3
FROM #AggData2 ad
LEFT OUTER JOIN #CompPriceTemp cp
ON ad.PART=cp.Part_No
and ad.[Month]=cp.[Month]
and ad.[Year]=cp.[Year]
GO
For each record in #AggData2, which is average price and volume by month for each part, I want to join the prices of the three competitors (A, B & C). Thus, I want to join based on Part, Month, and Year. Because some competitors don't offer all parts, I am using a LEFT OUTER JOIN. So, the resulting table (#AggData3), should have the exact same number of rows as the initial table (#AggData2), just with the three additional columns with competitor prices.
However, the new table (#AggData3), has ~35,000 more rows than #AggData2.
Any ideas why that is happening, and how to fix my query.

Because there are multiple rows in Table #CompPriceTemp that match to one row in #AggData2.
Is there one for each of three competitors perhaps? If that is so, then you need three joins, each to the same table, one for each of the 3 competitors?
But if there is supposed to be one row in #CompPriceTemp for each Month, Year, and product, with three separate columns one column for each competitor, then you have some bad data in there.

Wild guess:
ON ad.PART=cp.Part_No
and ad.[Month]=cp.[Month]
and ad.[Year]=cp.[Year]
This query does not uniquely identify rows in CP. Or CP has ~35000 duplicate rows.

Are you sure that you have only one matching row in CompPriceTemp for every single row in AggData2 ?

Related

Refer to different id's within the same query in SQL

I need to brind a lot of columns from several tables using LEFT JOIN. My starting point is the orders table and I bring the vendor name from the "Address_table". Then I add another table with order details and then the shipping information of each order detail.
My problem is that I need to bring a different record from "Address_table" to refer onether id's detailed in shipment table as of "origin_id" and "destination_id".
In other words, "address_id", "origin_id" and "destination_id" are all records from "Address_table". I brought the first one related to the vendor, how can I retrieve the other two?
Example
Thanks in advance
Your question is not exactly clear in terms of the tables and their relationships. It is, however, clear what the problem is. You need to join against the same table twice using different columns.
In order to do that you need to use table aliases. For example, you can do:
select *
from shipment s
left join address_table a on a.address_id = s.origin_id
left join address_table b on b.address_id = s.destination_id
In this example the table address_table is joined twice against the table shipment; the first time we use a as an alias, the second time b. This way you can differentiate how to pick the right columns and make the joins work as you need them to.

Outputting the data from several sql tables without having a common value

I have a select query which combined several tables. PRODUCTION_ORDER_RESULTS, PRODUCTION_ORDERS and SERVICE_GUARANTY_NEW have common value however STOCKS table does not.
SELECT PR_ORDERS.ARRIVED_CITY,
PR_ORDERS.MONTAJ_DATE,
PR_ORDER_RESULT.TRANSFER_DATE,
PR_ORDERS.P_ORDER_ID,
PR_ORDER_RESULT.P_ORDER_ID,
SG.SALE_CONSUMER_ID,
SG.IS_SERI_SONU,
S.BRAND_ID,
S.PROPERTY
FROM workcube_test_1.PRODUCTION_ORDER_RESULTS PR_ORDER_RESULT,
workcube_test_1.PRODUCTION_ORDERS PR_ORDERS,
workcube_test_1.SERVICE_GUARANTY_NEW SG,
workcube_test_1.STOCKS S
WHERE PR_ORDER_RESULT.P_ORDER_ID = PR_ORDERS.P_ORDER_ID
AND PR_ORDER_RESULT.PR_ORDER_ID = SG.PROCESS_ID
when I run the query, it shows the output as below.
The problem here is there are four data rows returned from PRODUCTION_ORDER_RESULTS, PRODUCTION_ORDERS, SERVICE_GUARANTY_NEW and once I have added the STOCKS table, arrived_city, montaj_date, transfer_date columns are side by side with STOCKS table's rows, but the columns value should be null, not filled with data.
The way I tried is UNION of STOCKS table, however unioned table values are ignored, can not use them in html blocks.
there needs to be at least one more join condition among tables where there's for STOCKS table, I think there might exist such a column STOCK_ID within a table such as PRODUCTION_ORDER_RESULTS in order to join with STOCKS table. I think this should be the reason for multiple returning rows. If there's no common column, then the returning data will be produced as many as the number of records within STOCK table due to existing CROSS JOIN logic within the current query. So rearrange your query as
SELECT PR_ORDERS.ARRIVED_CITY,
PR_ORDERS.MONTAJ_DATE,
PR_ORDER_RESULT.TRANSFER_DATE,
PR_ORDERS.P_ORDER_ID,
PR_ORDER_RESULT.P_ORDER_ID,
SG.SALE_CONSUMER_ID,
SG.IS_SERI_SONU,
S.BRAND_ID,
S.PROPERTY
FROM workcube_test_1.PRODUCTION_ORDER_RESULTS PR_ORDER_RESULT
JOIN workcube_test_1.PRODUCTION_ORDERS PR_ORDERS
ON PR_ORDER_RESULT.P_ORDER_ID = PR_ORDERS.P_ORDER_ID
JOIN workcube_test_1.SERVICE_GUARANTY_NEW SG
ON PR_ORDER_RESULT.PR_ORDER_ID = SG.PROCESS_ID
JOIN workcube_test_1.STOCKS S
ON PR_ORDER_RESULT.STOCK_ID = S.ID

getting duplicates when joining tables

I have two tables that I want to join. Table1 has sales order, but it doesn’t have the name of the sales person. It only has employee ID. I have table2, that has the names of employees, and employeeID is common between the two tables. Normally I would use an inner join to get the name of the sales person from table2. The problem is that on table2, there are multiple entries for each employee. If they changed manager, or changed roles within the company, or perhaps went on FMLA, it creates a new row. Therefore, when I join the tables, it creates duplicates because of the multiple entries in table2. A sale shows 3 or 4 times in my results.
Select
a.state_name
,order_number
,a.employeeID
,b.Sales_Rep_Name
,a.order_date
from
table1 as A
Inner join table2 as B
On a.employeeid = b.employeeID
where
b.monthperiod = 'November' <-- If I remove this one it adds duplicates
Is there a way to not get these duplicates? I tried distinct but didn’t work. Probably because the rows have at least one column different. I was able to eliminate the duplicates when I added a where clause asking for last month on table 2, but I am in a situation where I need all months, not just one. I have to manually change the month in order to get the full year.
Any help would be appreciated. Thanks
Use a subquery to get list of distinct employee records and then query the sales table

how can an unrelated table specified in FROM-clause affect the outcome of SUM()?

I am new to sqlite3 and have made some queries where the outcome seems strange to me. I have two tables, OrderDetails and Offices, that from their schema are unrelated. There are 7 entries in offices and 2996 in OrderDetails. Within OrderDetails, there is a column with quantityOrdered, and by summing the column values I get an accumulated value.
SELECT SUM(quantityOrdered) FROM OrderDetails; (result is 105516)
When I include the other table, which i don't actually extract any information from in my SELECT-clause and should be unrelated in attributes like so:
SELECT SUM(OD.quantityOrdered FROM OrderDetails OD, Offices; (result is 738612)
The result is much higher, and it is interesting to see that it is exactly 7 times larger (the number of entries in offices). I also get it even though I specify that it should only be OrderDetails attributes (OD.quantityOrdered). Is there some obvious logic that I don't see and understand? I hope someone can help me.
You are getting the sum for a CROSS JOIN since you dont have a JOIN condition.
Every row FROM the first table is JOINed to every other row from the other table.
Look here for a basic JOIN tutorial.
It should be
SELECT SUM(OD.quantityOrdered)
FROM OrderDetails OD JOIN Offices O
ON OD.somecol=O.someothercol
When you list two tables in a FROM clause but specify no conditions to relate them together, you get what is known as a CROSS JOIN, which calculates every possible combination of rows from the two tables.
You can see this by running
SELECT *
FROM OrderDetails, Offices
In more modern SQL that would be written
SELECT *
FROM OrderDetails
CROSS JOIN Offices
The SUM() function (without a GROUP BY) runs across all the rows in the result set, regardless of how the resultset was calculated (you can think of the SELECT clause running after the CROSS JOIN).
So your second query takes all the rows created by the CROSS JOIN and sums them up, meaning all the values are counted 7 times.
SELECT SUM(OD.quantityOrdered)
FROM OrderDetails as OD
CROSS JOIN Offices as O

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