How to improve code to include columns from another table? - sql

I'm trying to do a join statement for an inventory report of sorts but I am not sure what I am missing.
So I tried doing the reverse of my join statement and some columns remain omitted. I'm just not sure what I should add or change in the code.
My tables look something like this:
PRODUCT_TBL: productID|productDescription|stockQuantity
PRODUCT_SUPPLIER_TBL: supplierID|productID|vendorPartID|productCost|purchased Quantity
select PRODUCT_SUPPLIER_TBL.productID,PRODUCT_SUPPLIER_TBL.vendorPartID,PRODUCT_SUPPLIER_TBL.productCost
from PRODUCT_SUPPLIER_TBL
inner join PRODUCT_TBL on PRODUCT_SUPPLIER_TBL.productID = PRODUCT_TBL.productID
order by productCost desc
I expected one other column aside from productID to appear in the results but what I got only has information from the product_supplier_tbl and the productID from product_supplier_tbl and product_tbl.

You include any columns - from any of the tables you have joined together - in the SELECT list to return it in your query results.
select PRODUCT_SUPPLIER_TBL.productID
,PRODUCT_SUPPLIER_TBL.vendorPartID
,PRODUCT_SUPPLIER_TBL.productCost
,PRODUCT_TBL.product_description --adding a column to the SELECT list
from PRODUCT_SUPPLIER_TBL
inner join PRODUCT_TBL on PRODUCT_SUPPLIER_TBL.productID = PRODUCT_TBL.productID
order by productCost desc

Related

Microsoft SQL Server: Need to Compare Two Sets of Results

I have two queries that each give me list of orders and the number of line items on each order. We are migrating systems, and one is from the source, and the other from the target. I need to do some validation between them.
I want to compare them so that my result is a list of orders where the number of lines do not match. If an order should be in the target but isn't, it should also appear on the list.
I have been fighting with this for a full day and I cannot wrap my head around how to approach it.
Help would be appreciated!
Here are the two queries:
SOURCE QUERY
select s.oNum, count(s.oNum)
from SourceTbl s
left join PK_Master pk
on pk.Num = s.oNum
where s.oNum not in (select ordernum from tmpSalesOrders)
group by s.oNum
order by s.oNum
TARGET QUERY
select p.oNum, count(p.oNum)
from BridgeTbl p
left join TargetTbl t
on p.ToNum = t.orderID
group by p.oNum
order by p.oNum
SourceTable is a superset, and PK_Master and tmpSalesOrders are used to refine the orders that SHOULD be migrated.
The BridgeTbl has a field called SoNum that = s.oNum to link the source and target.
I need the source order number (s.oNum) in the result set.
Toss EXCEPT between those two queries and let 'er rip. That will tell you records that are outputted by your first query that aren't in your second query.
select s.oNum, count(s.oNum)
from SourceTbl s
left join PK_Master pk
on pk.Num = s.oNum
where s.oNum not in (select ordernum from tmpSalesOrders)
group by s.oNum
order by s.oNum
EXCEPT
select p.oNum, count(p.oNum)
from BridgeTbl p
left join TargetTbl t
on p.ToNum = t.orderID
group by p.oNum
order by p.oNum
EXCEPT is a "Set Operator". In TSQL you can UNION, UNION ALL, EXCEPT, and INTERSECT sets.

SQL columns that were Inner joined showing up separately?

I'm trying to join some tables together, but when I join them the columns I am joining on are showing up separately.
My code looks something like this:
Select * FROM
SimulationOutput as SO
Inner Join SimulationInput as SI
ON SO.Key = SI.Key
AND
SO.Scenario = SI.Scenario
When I do this, I get the result I expected but my result also includes duplicates of The "Key" columns and the "Scenario" columns that I just joined on.
Is this expected behavior?
https://www.w3schools.com/sql/trysql.asp?filename=trysql_select_join_inner
On that website
I ran the following code:
Select * FROM
Orders
Inner Join Customers ON Orders.CustomerID = Customers.CustomerID
ORDER BY Orders.CustomerID
And in that output, the CustomerId column only shows up once, the Customers.CustomerID was dropped. I am trying to understand why this is happening in the latter, but not the former.
The reason I ask is because I intend to use a series of nested tables. And I'm running into duplicate column problems where SQL doesn't know which Scenario column to choose. I understand that I can specify the specific column, but I was planning on specifying my specific columns at the top fo the nested loop, and use a series of nested Select* in between.
So the structure would be something like
Select Column1, Column2, Column3 From
(Select * FROM ......
(Select * FROM.......
(Select * FROM..... ) as T1) as T2) as T3
I understand that this may not be ideal and for this question my end result is moot, I want to understand why the columns I'm joining on aren't being dropped the way they are on the w3schools website.
Is it because I am using an AND statement? Is there a better way to inner join using multiple criteria? Is it because of my version of SQL (TSQL?)
Image From W3 schools output

Specifying SELECT, then joining with another table

I just hit a wall with my SQL query fetching data from my MS SQL Server.
To simplify, say i have one table for sales, and one table for customers. They each have a corresponding userId which i can use to join the tables.
I wish to first SELECT from the sales table where say price is equal to 10, and then join it on the userId, in order to get access to the name and address etc. from the customer table.
In which order should i structure the query? Do i need some sort of subquery or what do i do?
I have tried something like this
SELECT *
FROM Sales
WHERE price = 10
INNER JOIN Customers
ON Sales.userId = Customers.userId;
Needless to say this is very simplified and not my database schema, yet it explains my problem simply.
Any suggestions ? I am at a loss here.
A SELECT has a certain order of its components
In the simple form this is:
What do I select: column list
From where: table name and joined tables
Are there filters: WHERE
How to sort: ORDER BY
So: most likely it was enough to change your statement to
SELECT *
FROM Sales
INNER JOIN Customers ON Sales.userId = Customers.userId
WHERE price = 10;
The WHERE clause must follow the joins:
SELECT * FROM Sales
INNER JOIN Customers
ON Sales.userId = Customers.userId
WHERE price = 10
This is simply the way SQL syntax works. You seem to be trying to put the clauses in the order that you think they should be applied, but SQL is a declarative languages, not a procedural one - you are defining what you want to occur, not how it will be done.
You could also write the same thing like this:
SELECT * FROM (
SELECT * FROM Sales WHERE price = 10
) AS filteredSales
INNER JOIN Customers
ON filteredSales.userId = Customers.userId
This may seem like it indicates a different order for the operations to occur, but it is logically identical to the first query, and in either case, the database engine may determine to do the join and filtering operations in either order, as long as the result is identical.
Sounds fine to me, did you run the query and check?
SELECT s.*, c.*
FROM Sales s
INNER JOIN Customers c
ON s.userId = c.userId;
WHERE s.price = 10

Getting way more results than expected in SQL left join query

My code is such:
SELECT COUNT(*)
FROM earned_dollars a
LEFT JOIN product_reference b ON a.product_code = b.product_code
WHERE a.activity_year = '2015'
I'm trying to match two tables based on their product codes. I would expect the same number of results back from this as total records in table a (with a year of 2015). But for some reason I'm getting close to 3 million.
Table a has about 40,000,000 records and table b has 2000. When I run this statement without the join I get 2,500,000 results, so I would expect this even with the left join, but somehow I'm getting 300,000,000. Any ideas? I even refered to the diagram in this post.
it means either your left join is using only part of foreign key, which causes row multiplication, or there are simply duplicate rows in the joined table.
use COUNT(DISTINCT a.product_code)
What is the question are are trying to answer with the tsql?
instead of select count(*) try select a.product_code, b.product_code. That will show you which records match and which don't.
Should also add a where b.product_code is not null. That should exclude the records that don't match.
b is the parent table and a is the child table? try a right join instead.
Or use the table's unique identifier, i.e.
SELECT COUNT(a.earned_dollars_id)
Not sure what your datamodel looks like and how it is structured, but i'm guessing you only care about earned_dollars?
SELECT COUNT(*)
FROM earned_dollars a
WHERE a.activity_year = '2015'
and exists (select 1 from product_reference b ON a.product_code = b.product_code)

How to select all attributes in sql Join query

The following sql query below produces the specified result.
select product.product_no,product_type,salesteam.rep_name,salesteam.SUPERVISOR_NAME
from product
inner join salesteam
on product.product_rep=salesteam.rep_id
ORDER BY product.Product_No;
However my intensions are to further produce a more detailed result which will include all the attributes in the PRODUCT table. my approach is to list all the attributes in the first line of the query.
select product.product_no,product.product_date,product.product_colour,product.product_style,
product.product_age product_type,salesteam.rep_name,salesteam.SUPERVISOR_NAME
from product
inner join salesteam
on product.product_rep=salesteam.rep_id
ORDER BY product.Product_No;
Is there another way it can be done instead of listing all the attributes of PRoduct table one by one?
You can use * to select all columns from all tables, or you can use [table/alias].* to select all columns from the specified table. In your case, you can use product.*:
select product.*,salesteam.rep_name,salesteam.SUPERVISOR_NAME
from product
inner join salesteam
on product.product_rep=salesteam.rep_id
ORDER BY product.Product_No;
It is important to note that you should only do this if you are 100% sure you need every single column, and always will. There are performance implications associated with this; if you're selecting 100 columns from a table when you really only need 4 or 5 of them, you're adding a lot of overhead to the query. The DBMS has to work harder, and you're also sending more data across the wire (if your database is not on the same machine as your executing code).
If any columns are later added to the product table, those columns will also be returned by this query in the future.
select
product.*,
salesteam.rep_name,
salesteam.SUPERVISOR_NAME
from product inner join salesteam on
product.product_rep=salesteam.rep_id
ORDER BY
product.Product_No;
This should do.
You can write like this
select P.* --- all Product columns
,S.* --- all salesteam columns
from product P
inner join salesteam S
on P.product_rep=S.rep_id
ORDER BY P.Product_No;