SQL query table inner join - sql

I'm having a issue where the SKU doesn't match the correct lines via the color. The csv rows / items do not match and there seems to be a lot of duplicates the DIM_1_UPR field in the csv needs to match the SKU, BARCODE, and VENDOR_SKU fields. I think I messed up my inner join.
Here is a screen shot with one item.. you can see it is showing 288 rows. It is duplicating the same thing multiple times and the SKU / VENDOR_SKU / BARCODE basically everything from USR_MAG_ITEM_EXP doesn't match or line up correctly with the rest of the table :
Do I have to do all keys or can I just use the one ITEM_NO?
Keys
Here is my code:
SELECT
dbo.IM_PRC.ITEM_NO, dbo.IM_PRC.REG_PRC, dbo.IM_PRC.PRC_1,
dbo.IM_PRC.PRC_2,dbo.IM_ITEM.CATEG_COD,
dbo.IM_ITEM.SUBCAT_COD, dbo.IM_ITEM.STAT, dbo.IM_ITEM.LST_COST,
dbo.IM_ITEM.USER_MAG_NAME, dbo.IM_INV_CELL.LOC_ID,
dbo.IM_INV_CELL.DIM_1_UPR, dbo.IM_INV_CELL.MIN_QTY, dbo.IM_INV_CELL.MAX_QTY,
dbo.IM_INV_CELL.QTY_ON_HND, dbo.USR_MAG_ITEM_EXP.SKU,
dbo.USR_MAG_ITEM_EXP.VENDOR_SKU,
dbo.USR_MAG_ITEM_EXP.BARCOD
FROM dbo.IM_PRC
INNER JOIN dbo.IM_ITEM ON dbo.IM_PRC.ITEM_NO = dbo.IM_ITEM.ITEM_NO
INNER JOIN dbo.IM_INV_CELL ON dbo.IM_INV_CELL.ITEM_NO = dbo.IM_PRC.ITEM_NO
INNER JOIN dbo.USR_MAG_ITEM_EXP ON dbo.USR_MAG_ITEM_EXP.ITEM_NO =
dbo.IM_PRC.ITEM_NO
WHERE dbo.IM_INV_CELL.LOC_ID IN ('01', '03', '11', '12', '14', '23') and
dbo.IM_ITEM.ITEM_NO = 'grohrostbk'
ORDER BY IM_INV_CELL.LOC_ID ASC
Edit : so doing a full outter join and adding the extra syntax for joining that aaron suggested gave me no duplicates! But
how do I include our parent products that do not have a color or add a empty DIM_1_UPR for example I want the top line to be included in the major sheet - SELECT top 5 item_no, name, sku, DIM_1_UPR, vendor_sku FROM dbo.USR_MAG_ITEM_EXP WHERE ITEM_NO = 'grohrostbk' screen: pic

If you look at the screen shot screen you can see that the first LINE has a DIM_1_UPR of "*" and a VENDOR_SKU of "HROSTBK" but when I run the main joined sheet I do not see this LINE because it has a * and no color. Any thoughts on how to include it?

Related

SQL report filtering, results stop after first item

and thanks in advance. I am a newbie, working on one of my first reports. I have orders, which have a terminal assigned them (a "DC"). The report is set up to return all open orders, the "DC", and a few other columns (driver #, city, etc). I made a drop down filter to use so I can look at one, several, or all of the DCs. My problem is, it stops looking after the first item that is checked in the drop down list. So if the first item in the list has 100 orders, but the rest of them have thousands more, it only shows me the 100 orders. Am I making any sense here? I am not sure what information from my report's setup would be pertinent here.
This is the query that the report is based on. Using SQL Report Builder.
SELECT
o.OrderTrackingID,
cm.accountno,
o.ClientRefNo,
o.DCoName,
o.DStreet,
o.DCity,
o.DState,
o.DZip,
o.DZone,
t.TerminalName as 'OrderDC',
e.LastName as 'DrvLast',
e.FirstName as 'DrvFirst',
e.DriverNo,
et.TerminalName as 'DriverDC'
FROM Orders o
FULL JOIN OrderDrivers od ON o.OrderTrackingID = od.OrderTrackingID
FULL JOIN Employees e ON od.DriverID = e.ID
FULL JOIN ClientMaster cm ON o.ClientID = cm.ClientID
FULL JOIN Terminals t ON o.TerminalID = t.TerminalID
FULL JOIN Terminals et ON e.TerminalID = et.TerminalID
WHERE o.Status = 'N'
Order By o.aTimeStamp ASC
(I am writing this as an answer even if it isn't an complete answer mostly because the comment field is kind of limited.)
In the SQL you posted the below stands out as wrong
FULL JOIN Terminals t ON o.TerminalID = t.TerminalID
FULL JOIN Terminals et ON e.TerminalID = et.TerminalID
You are joining the same table twice but the is nothing that separated the two joins and this is my guess why you are not getting any more orders in your report.
I don't now what the drop down list corresponds to but I assume it is some kind of identifier in the Terminals table.
From a pure SQL point of view I would expect something like this
FULL JOIN Terminals t ON o.TerminalID = t.TerminalID
WHERE t.someColumn IN (value1, value2)
where value1 and value2 comes from the drop down list.
I see in your select part that you include the same column from both of the Terminals JOIN you have and I expect those two columns to always have the same values. You should need that column only once in your select list.
Not a solution but maybe this can get you in the right direction.

INNER JOIN WITH LIKE AND PREFIX

ITEM1 in table A and B-ITEM1 in Table B, I want to join them so A-ITEM1 = B-ITEM with an inner join since they are the same thing only with different prefix. Any help would be appreciated.
/*My scripts*/
SELECT TOP 50
A.ITEMNMBR AS 'Item Number',
A.QTYONHND AS 'Quantity On Hand'
FROM [NSR].dbo.[IV00102] A
INNER JOIN [ART].dbo.[IV00101] B
ON A.ITEMNMBR = B.ITEMNMBR
ORDER BY A.ITEMNMBR
/The problem with that part is in NSR database the itemnumber is NSR-ITEM1 and for the ART database the item number = ART-ITEM1/
/I want the result to show... because is the same item/
ITEMNMBR QTYONHND
NSR-ITEM1 12
ART-ITEM1 12
You can use string functions in ON clauses.
Perhaps this one will help.
ON REPLACE(A.ITEMNBR, 'NSR-', 'ART-') = B.ITEMNBR
This will "repair" values like NSR-ITEM1 by turning them into ART-ITEM1. Then they can be tested for equality.
But, to be clear, this is not a great solution to your problem. It's brittle because you may have ITEMNBR values that don't follow the NSR-whatever pattern. Those will not match.

Access SQL query without duplicate results

I made a query and wanted to not have any duplicates but i got some times 3 duplicates and when i used DISTINCT or DISTINCTROW i got only 2 duplicates.
SELECT f.flight_code,
f.status,
a.airport_name,
a1.airport_name,
f.departing_date+f.departing_time AS SupposedDepartingTime,
f.landing_date+f.landing_time AS SupposedLandingTime,
de.actual_takeoff_date+de.actual_takeoff_time AS ActualDepartingTime,
SupposedLandingTime+(ActualDepartingTime-SupposedDepartingTime) AS ActualLandingTime
FROM
(((Flights AS f
LEFT JOIN Aireports AS a
ON a.airport_code = f.depart_ap)
LEFT JOIN Aireports AS a1
ON f.target_ap = a1.airport_code)
LEFT JOIN Irregular_Events AS ie
ON f.flight_code = ie.flight_code)
LEFT JOIN Delay_Event AS de
ON ie.IE_code = de.delay_code;
had to use LEFT JOIN because when i used INNER JOIN i missed some of the things i wanted to show because i wanted to see all the flights and not only the flights that got delayed or canceled.
This is the results when i used INNER JOIN, you can see only the flights that have the status "ביטול" or "עיכוב" and that is not what i wanted.
[the results with LEFT JOIN][2]
[2]: https://i.stack.imgur.com/cgE2G.png
and when i used DISTINCT where you see the rows with the NUMBER 6 on the first column it appear only two times
IMPORTANT!
I just checked my query and all the tables i use there and i saw my problem but dont know how to fix it!
in the table Irregular_Events i have more the one event for flights 3,6 and 8 and that is why when i use LEFT JOIN i see more even thou i use distinct, please give me some help!
Not entirely sure without seeing the table structure, but this might work:
SELECT f.flight_code,
f.status,
a.airport_name,
a1.airport_name,
f.departing_date+f.departing_time AS SupposedDepartingTime,
f.landing_date+f.landing_time AS SupposedLandingTime,
de.actual_takeoff_date+de.actual_takeoff_time AS ActualDepartingTime,
SupposedLandingTime+(ActualDepartingTime-SupposedDepartingTime) AS ActualLandingTime
FROM
((Flights AS f
LEFT JOIN Aireports AS a
ON a.airport_code = f.depart_ap)
LEFT JOIN Aireports AS a1
ON f.target_ap = a1.airport_code)
LEFT JOIN
(
SELECT
ie.flight_code,
de1.actual_takeoff_date,
de1.actual_takeoff_time
FROM
Irregular_Events ie
INNER JOIN Event AS de1
ON ie.IE_code = de1.delay_code
) AS de
ON f.flight_code = de.flight_code
It is hard to tell what is the problem with your query without any sample of the output, and without any description of the structure of your tables.
But your problem is that your are querying from the flights table, which [I assume] can be linked to multiple irregular_events, which can possibly also be linked to multiple delay_event.
If you want to get only one row per flight, you need to make sure your joins return only one row too. Maybe you can do it by adding one more condition to the join, or by adding a condition in a sub-query.
EDIT
You could try to add a GROUP BY to the query:
GROUP BY
f.flight_code,
f.status,
a.airport_name,
a1.airport_name;

Grouping by all non-aggregated columns in MSSQL

Suppose I have two tables PO and PO_Line and I want to list all fields from PO plus the quantity of rows from PO_Line that link back to each row in PO I would write a query something like -
SELECT
PO.propA,
PO.propB,
PO.propC,
PO.propD,
PO.propE,
...
PO.propY,
COUNT(PO_Line.propA) LINES
FROM
PO
LEFT JOIN
PO_Lines
ON
PO.ID = PO_Lines.PO_ID
Obviously this would give an error someting along the lines of -
Column 'PO.propA' is invaalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
So to get the query to run I will add a GROUP BY clause to the end of the query and copy and paste my select lines, like so -
SELECT
PO.propA,
PO.propB,
PO.propC,
PO.propD,
PO.propE,
...
PO.propY,
COUNT(PO_Line.propA) LINES
FROM
PO
LEFT JOIN
PO_Lines
ON
PO.ID = PO_Lines.PO_ID
GROUP BY
PO.propA,
PO.propB,
PO.propC,
PO.propD,
PO.propE,
...
PO.propY
Which works perfectly however it all feels a little unwieldy, especially if I've named my columns i.e. -
SELECT
PO.propA AS 'FIRST PROPERTY',
PO.propB AS 'SECOND PROPERTY',
PO.propC AS 'THIRD PROPERTY',
PO.propD AS 'ANOTHER PROPERTY',
PO.propE AS 'YOU GET THE IDEA',
...
PO.propY
and I have to copy/paste the entries from the select clause and then delete the column names.
So my question is - Is there a shorthand method to say group by all non-aggregated entries found in the select clause?
I think you just want window functions:
SELECT . . .,
COUNT(PO_Line.propA) OVER (PARTITION BY PO.ID) as LINES
FROM PO LEFT JOIN
PO_Lines
ON PO.ID = PO_Lines.PO_ID;
I have to copy/paste the entries from the select clause and then delete the column names.
I strongly suggest to use block/column selection.Move , as first element and allign your aliases:
SELECT
PO.propA AS 'FIRST PROPERTY'
,PO.propB AS 'SECOND PROPERTY'
,PO.propC AS 'THIRD PROPERTY'
,PO.propD AS 'ANOTHER PROPERTY'
,PO.propE AS 'YOU GET THE IDEA'
...
,PO.propY
,COUNT(PO_Line.propA) LINES
FROM PO
LEFT JOIN PO_Lines
ON PO.ID = PO_Lines.PO_ID
GROUP BY
...
In SQL Server Management Studio use simple block selection SHIFT + ALT highlight and paste.
If you are using other editor find corresponding keyshortcut here.
It is nice for multiple edit at once like adding schema, alias, ...and so on.
Reading your query I think you might not need a GROUP BY to begin with:
SELECT
PO.propA,
PO.propB,
PO.propC,
PO.propD,
PO.propE,
...
PO.propY,
(SELECT COUNT(*) FROM PO_Lines WHERE PO.ID = PO_Lines.PO_ID) LINES
FROM
PO

Merge / Join SQL Select Queries

I am struggling with combining the below Select Statments, I know I could cheat and add some fake columns in and then use Union, but I want to do this correctly.
Once I have them joined, I will be putting the Statment in to a XML file for use with Word and CRM4.
SELECT BILLTO_NAME,
BILLTO_LINE1,
BILLTO_LINE2,
BILLTO_LINE3,
BILLTO_CITY,
BILLTO_COUNTRY,
BILLTO_POSTALCODE,
ORDERNUMBER,
REQUESTDELIVERYBY,
MODIFIEDON,
SHIPTO_NAME,
SHIPTO_LINE1,
SHIPTO_LINE2,
SHIPTO_LINE3,
SHIPTO_CITY,
SHIPTO_STATEORPROVINCE,
SHIPTO_COUNTRY,
SHIPTO_POSTALCODE,
CREATEDBY
FROM SALESORDERBASE
SELECT QUANTITY,
DESCRIPTION
FROM SALESORDERDETAILBASE
SELECT NEW_ORDERNOTES,
NEW_NOTES
FROM SALESORDEREXTENSIONBASE
They all have the common column of SalesOrderID, which I need to add in somewhere as well.
You can use a LEFT JOIN on the tables:
SELECT ob.SalesOrderID
ob.BILLTO_NAME,
ob.BILLTO_LINE1,
ob.BILLTO_LINE2,
ob.BILLTO_LINE3,
ob.BILLTO_CITY,
ob.BILLTO_COUNTRY,
ob.BILLTO_POSTALCODE,
ob.ORDERNUMBER,
ob.REQUESTDELIVERYBY,
ob.MODIFIEDON,
ob.SHIPTO_NAME,
ob.SHIPTO_LINE1,
ob.SHIPTO_LINE2,
ob.SHIPTO_LINE3,
ob.SHIPTO_CITY,
ob.SHIPTO_STATEORPROVINCE,
ob.SHIPTO_COUNTRY,
ob.SHIPTO_POSTALCODE,
ob.CREATEDBY,
od.QUANTITY,
od.DESCRIPTION,
oe.NEW_ORDERNOTES,
oe.NEW_NOTES
FROM SALESORDERBASE ob
LEFT JOIN SALESORDERDETAILBASE od
on ob.SalesOrderID = od.SalesOrderID
LEFT JOIN SALESORDEREXTENSIONBASE oe
on ob.SalesOrderID = oe.SalesOrderID
Assuming the column that identifies the relationship is called id on all three tables, you can do this:
SELECT sob.BILLTO_NAME,
sob.BILLTO_LINE1,
sob.BILLTO_LINE2,
sob.BILLTO_LINE3,
sob.BILLTO_CITY,
sob.BILLTO_COUNTRY,
sob.BILLTO_POSTALCODE,
sob.ORDERNUMBER,
sob.REQUESTDELIVERYBY,
sob.MODIFIEDON,
sob.SHIPTO_NAME,
sob.SHIPTO_LINE1,
sob.SHIPTO_LINE2,
sob.SHIPTO_LINE3,
sob.SHIPTO_CITY,
sob.SHIPTO_STATEORPROVINCE,
sob.SHIPTO_COUNTRY,
sob.SHIPTO_POSTALCODE,
sob.CREATEDBY,
sodb.QUANTITY,
sodb.DESCRIPTION,
soeb.NEW_ORDERNOTES,
soeb.NEW_NOTES
From SalesOrderBase sob
JOIN SalesOrderDetailBase sodb
ON sob.id = sodb.SalesOrderID
JOIN SalesOrderExtensionBase soeb
ON sob.id = soeb.SalesOrderID
You can think of JOINing as slamming together rows side-by-side, whereas UNIONing is slamming together rows one on top of the other. UNIONS require that the columns be the same and JOINs require that there is a relationship of some kind between each row.
EDIT - The OP provided more details