Using an except statement with Alias tables - sql-server

I probably didn't label that right but am not all that great at sql. The short of the problem is I am having to find parts that are used to make up a product, but are use ONLY for that product and not any other product. I was trying to accomplish this with e except statement but kept getting an error with the end and i'm stuck. Any help would be appreciated. Thanks.
Select A.Component_Part From (Select * From (SELECT T.Component_Part, View_BOM_FG_ALL_v2_1.FGITEM, IM.IM_Inv_Type
FROM IM INNER JOIN
View_BOM_FG_ALL_v2 AS View_BOM_FG_ALL_v2_1 ON IM.IM_Part_Nbr = View_BOM_FG_ALL_v2_1.FGITEM RIGHT OUTER JOIN
(SELECT Component_Part
FROM View_BOM_FG_ALL_v2
WHERE (FGITEM = 'SPZ-9')) AS T ON View_BOM_FG_ALL_v2_1.Component_Part = T.Component_Part
WHERE (View_BOM_FG_ALL_v2_1.FGITEM <> 'SPZ-9') AND (T.Component_Part NOT LIKE '%30-') and IM.IM_Inv_Type = 'F') AS A
Join
(Select * From (SELECT C.Component_Part, View_BOM_FG_ALL_v2_1.FGITEM, IM.IM_Inv_Type
FROM IM INNER JOIN
View_BOM_FG_ALL_v2 AS View_BOM_FG_ALL_v2_1 ON IM.IM_Part_Nbr = View_BOM_FG_ALL_v2_1.FGITEM RIGHT OUTER JOIN
(SELECT Component_Part
FROM View_BOM_FG_ALL_v2
WHERE (FGITEM = 'SPZ-9')) AS C ON View_BOM_FG_ALL_v2_1.Component_Part = C.Component_Part
WHERE (View_BOM_FG_ALL_v2_1.FGITEM = 'SPZ-9') AND (C.Component_Part NOT LIKE '%30-') and IM.IM_Inv_Type = 'F') AS B
Except
Select * From (SELECT T.Component_Part, View_BOM_FG_ALL_v2_1.FGITEM, IM.IM_Inv_Type
FROM IM INNER JOIN
View_BOM_FG_ALL_v2 AS View_BOM_FG_ALL_v2_1 ON IM.IM_Part_Nbr = View_BOM_FG_ALL_v2_1.FGITEM RIGHT OUTER JOIN
(SELECT Component_Part
FROM View_BOM_FG_ALL_v2
WHERE (FGITEM = 'SPZ-9')) AS T ON View_BOM_FG_ALL_v2_1.Component_Part = T.Component_Part
WHERE (View_BOM_FG_ALL_v2_1.FGITEM <> 'SPZ-9') AND (T.Component_Part NOT LIKE '%30-') and IM.IM_Inv_Type = 'F') AS A

Related

Turn Date into Column with Pivot

Im not good at using Pivot but i think that's the only way to solve my Problem.
I have this SQL
SELECT DISTINCT ADR_Adressen.AdressNrADR
, LEFT(ADR_Adressen.Name, 3) AS Name
, LEFT(ADR_Adressen.Vorname, 3) AS Vorname
, CRM_Aufgaben.TerminVon
, LAG_Artikel.ArtikelNrLAG
, CRM_AufgabenLink.MitNrPRO
FROM ADR_Adressen
INNER JOIN PRO_Auftraege ON ADR_Adressen.AdressNrADR = PRO_Auftraege.Kunde
INNER JOIN CRM_Aufgaben ON PRO_Auftraege.AuftragNrPRO = CRM_Aufgaben.AuftragNrPRO
INNER JOIN CRM_Status ON CRM_Aufgaben.StatusCRM = CRM_Status.StatusCRM
INNER JOIN LAG_Artikel ON CRM_Aufgaben.ArtikelNrLAG = LAG_Artikel.ArtikelNrLAG
INNER JOIN ADR_GruppenLink ON ADR_Adressen.AdressNrADR = ADR_GruppenLink.AdressNrADR
INNER JOIN ADR_Gruppen ON ADR_GruppenLink.GruppeADR = ADR_Gruppen.GruppeADR
INNER JOIN CRM_AufgabenLink ON CRM_Aufgaben.AufgabenNrCRM = CRM_AufgabenLink.AufgabenNrCRM
WHERE { d '2016-03-07'} <= CRM_Aufgaben.TerminVon
AND { d '2016-03-11'} + 1 >= CRM_Aufgaben.TerminBis
AND CRM_AufgabenLink.MitNrPRO != 0
AND ADR_Gruppen.GruppeADR IN ( 'KIND' )
This is my result:
My wish is to get a Output like this:
The different Dates in TerminVon has to be Columns with the Values from ArtikelNrLAG+MitNrPRO. If the same AdressNrADR has more then one TerminVon on the same Date i have to make more rows. (Example where Name = Boc,Alt)
Can someone help me please =)
To PIVOT what you have, you can use a query similar to this.
SELECT AdressNrADR,
Name,
Vorname,
[2016-03-07],
[2016-03-08],
[2016-03-09],
[2016-03-10],
[2016-03-11]
FROM (
SELECT DISTINCT
ADR_Adressen.AdressNrADR,
LEFT(ADR_Adressen.Name,3) AS Name,
LEFT(ADR_Adressen.Vorname,3) AS Vorname,
CONVERT(VARCHAR(10), CRM_Aufgaben.TerminVon, 120) AS TerminVon, -- Convert date to yyyy-mm-dd format
LAG_Artikel.ArtikelNrLAG + '+' + CRM_AufgabenLink.MitNrPRO AS [Value], -- Combine column values
ROW_NUMBER() OVER
(PARTITION BY AdressNrADR,
LEFT(ADR_Adressen.Name,3),
LEFT(ADR_Adressen.Vorname,3),
CAST(CRM_Aufgaben.TerminVon AS DATE)
ORDER BY CRM_Aufgaben.TerminVon) Rn -- So we can get 1 row per time value
FROM ADR_Adressen
INNER JOIN PRO_Auftraege ON ADR_Adressen.AdressNrADR = PRO_Auftraege.Kunde
INNER JOIN CRM_Aufgaben ON PRO_Auftraege.AuftragNrPRO = CRM_Aufgaben.AuftragNrPRO
INNER JOIN CRM_Status ON CRM_Aufgaben.StatusCRM = CRM_Status.StatusCRM
INNER JOIN LAG_Artikel ON CRM_Aufgaben.ArtikelNrLAG = LAG_Artikel.ArtikelNrLAG
INNER JOIN ADR_GruppenLink ON ADR_Adressen.AdressNrADR = ADR_GruppenLink.AdressNrADR
INNER JOIN ADR_Gruppen ON ADR_GruppenLink.GruppeADR = ADR_Gruppen.GruppeADR
INNER JOIN CRM_AufgabenLink ON CRM_Aufgaben.AufgabenNrCRM = CRM_AufgabenLink.AufgabenNrCRM
WHERE { d '2016-03-07'} <= CRM_Aufgaben.TerminVon
AND { d '2016-03-11'} + 1 >= CRM_Aufgaben.TerminBis
AND CRM_AufgabenLink.MitNrPRO != 0
AND ADR_Gruppen.GruppeADR IN ('KIND')
) t
PIVOT (
MAX([Value])
FOR TerminVon IN ([2016-03-07],[2016-03-08],[2016-03-09],[2016-03-10],[2016-03-11])
) p
If you get that query to work. Your next step would be to make it Dynamic.
The difficult part of using t-sql's pivot functionality is that the output column names have to be hard coded. In your example we would need to know the value of each date and use that in the query in order to get the matching values by date. Fortunately other fine developers have experienced this frustration for us and have created scripts that will generate a dynamic pivot. I have included two links that will help you on your way.
https://www.mssqltips.com/sqlservertip/2783/script-to-create-dynamic-pivot-queries-in-sql-server/
http://sqlhints.com/2014/03/18/dynamic-pivot-in-sql-server/

TSQL Inner select using outer join

I have a query that is working for the most part until I had to add the inner select for "Trainers".
As you can see in the code below, I am trying to get all of the trainers for each of the segment ID's.
I am getting an error on the first inner selects where clause WHERE trn.segmentID = tes.teSegmentID saying that tes.teSegmentID is not defined.
Is there another way to approach this query in order to get the trainers like I am trying to accomplish?
SELECT *,
(SELECT e2.[FirstName] AS trainerFirst,
e2.[LastName] AS trainerLast
FROM BS_Training_Trainers AS trn
LEFT OUTER JOIN
employeeTable AS e2
ON trn.trainerEmpID = e2.EmpID
WHERE trn.segmentID = tes.teSegmentID
FOR XML PATH ('trainer'), TYPE, ELEMENTS, ROOT ('trainers'))
FROM dbo.BS_TrainingEvents AS a
WHERE a.trainingEventID IN (SELECT tes.trainingEventID
FROM dbo.BS_TrainingEvent_Segments AS tes
INNER JOIN
dbo.BS_TrainingEvent_SegmentDetails AS tesd
ON tesd.segmentID = tes.teSegmentID
INNER JOIN
dbo.BS_LocaleCodes AS locale
ON locale.localeID = tesd.localeID
WHERE locale.location = 'Baltimore');
It seems like you're taking the scenic route towards this:
SELECT a.*,
X.[FirstName],
X.[LastName]
FROM dbo.BS_TrainingEvents AS a
LEFT OUTER JOIN (SELECT e2.[FirstName], e2.[LastName], locale.location FROM dbo.BS_TrainingEvent_Segments AS tes
INNER JOIN dbo.BS_Training_Trainers AS trn ON trn.segmentID = tes.teSegmentID
INNER JOIN dbo.BS_TrainingEvent_SegmentDetails AS tesd ON tesd.segmentID = tes.teSegmentID
INNER JOIN dbo.BS_LocaleCodes AS locale ON locale.localeID = tesd.localeID
LEFT OUTER JOIN employeeTable AS e2 ON trn.trainerEmpID = e2.EmpID) AS X ON a.trainingEventID = X.trainingEventID
WHERE X.location = 'Baltimore';
Not sure if I got all those joins right, it was hard to decode from all the nesting you have going on.
If I have guessed table relationships from their names correctly, the only way to solve this is to reference the same filtering condition twice: first, in the XML generation part, and second in the outer level of the query:
with cte as (
select distinct tes.trainingEventID, tes.teSegmentID
from dbo.BS_TrainingEvent_Segments AS tes
INNER JOIN dbo.BS_TrainingEvent_SegmentDetails AS tesd ON tesd.segmentID = tes.teSegmentID
INNER JOIN dbo.BS_LocaleCodes AS locale ON locale.localeID = tesd.localeID
WHERE locale.location = 'Baltimore'
)
SELECT a.*, (
SELECT e2.[FirstName] AS trainerFirst, e2.[LastName] AS trainerLast
FROM BS_Training_Trainers AS trn
LEFT OUTER JOIN employeeTable AS e2 ON trn.trainerEmpID = e2.EmpID
inner join cte c on trn.segmentID = c.teSegmentID
FOR XML PATH ('trainer'), TYPE, ELEMENTS, ROOT ('trainers')
)
FROM dbo.BS_TrainingEvents AS a
where exists (select 0 from cte c where c.testrainingEventID = a.trainingEventID);
It's difficult to tell whether this is completely correct, of course, but I hope you get the idea.
Oh yes, and if you would have an event with multiple Baltimore segments, you will never be able to tell which trainer takes which one. But you can always add more data into XML to resolve this.

sql query assistance

I have a sql that is as under:
SELECT ib.branch_no,
ib.on_hand,
p.weightedav,
p.item_code,
FROM physical p
INNER JOIN
item_branch as ib on p.item_code = ib.item_code
WHERE ib.on_hand <> 0
This SQL returns only those branch_no that have on_hand <> 0.
I am trying to get all the branch_nos irrespective of the on_hand field, but while still using the where on_hand clause.
Taking the on_hand clause away solves my problem, but gives me large amount of un-needed rows with 0's.
I am using SQL SERVER 2008 R2.
Thanks in advance for any guidance. Please apologize if I am missing any information.
------------------------------------------ENTIRE SQL QUERY (Updated)---------------------------------------------
select
ib.branch_no,
p.weighted_av,
p.item_code,
p.x_value,
p.y_value,
ib.on_hand,
p.on_hand as PhysicalOH,
ip.price,
i.item_code as StyleCode,
i.description,
i.cat1,
i.cat2,
i.cat3,
i.cat4,
np.is_style_yn,
si.supplier_code ,
ysv.sort as YSort
from physical as p
left outer JOIN
item_branch as ib on p.item_code = ib.item_code -- and ib.on_hand <> 0
INNER JOIN
item_price as ip on p.item_code = ip.item_code and ip.price_type = 'P1'
INNER JOIN
style_values as sv on p.style_code = sv.style_code and p.x_value = sv.value
INNER JOIN
style_values as ysv on p.style_code = ysv.style_code and p.y_value = ysv.value and ysv.axis = 'Y'
INNER JOIN
ITEM as i on p.style_code = i.item_code
INNER JOIN
NON_PHYSICAL as np ON i.item_code = np.item_code and np.is_style_yn = 1
INNER JOIN
supplier_item as si ON i.item_code = si.item_code and si.pref_supp_no = 1
where --ib.on_hand <> 0 and
sv.axis = 'X' and
i.item_code in
(SELECT ITEM.item_code
FROM ITEM
INNER JOIN
NON_PHYSICAL ON ITEM.item_code = NON_PHYSICAL.item_code
LEFT JOIN
supplier_item ON Item.item_code = supplier_item.item_code and pref_supp_no = 1
WHERE NON_PHYSICAL.is_style_yn = 1 and ITEM.cat1 = 'Verge Sportswear Ltd' )
order by
si.supplier_code,
i.cat4,
i.cat3,
i.cat2,
i.cat1,
sv.sort
Try this:
SELECT ib.branch_no,
ib.on_hand,
p.weightedav,
p.item_code,
FROM physical p
INNER JOIN
item_branch as ib on (p.item_code = ib.item_code AND ib.on_hand <> 0)

How do I convert this Informix nested join to a tsql nested join?

I'm having a real hard time with this conversion. Those nested OUTER joins are a first to me.
Original Informix query:
from ttdpur401105 tdpur401
, ttdpur400105 tdpur400
-- Problem is here
, outer tarpur002105 arpur002
, outer (ttdpur402105 tdpur402, outer (ttisfc001105 tisfc001 , outer ttcibd001105 tcibd001a ))
, outer ttcibd001105 tcibd001
-- Problem is here
WHERE tdpur401.t_otbp = ' WD005'
and ((tdpur401.t_oltp=1 AND tdpur401.t_qibo <>0) OR(tdpur401.t_oltp=4 AND tdpur401.t_qibo = 0 AND tdpur401.t_qidl<>tdpur401.t_qoor))
and tdpur401.t_fire <> 1
and tdpur401.t_orno = tdpur400.t_orno
and (tdpur400.t_hdst<>25 AND tdpur400.t_hdst<>30 AND tdpur400.t_hdst<>40)
and arpur002.t_orno = tdpur401.t_orno
and arpur002.t_pono = tdpur401.t_pono
and tdpur402.t_orno = tdpur401.t_orno
and tdpur402.t_pono = tdpur402.t_pono
and tisfc001.t_pdno = tdpur402.t_pdno
and tcibd001.t_item = tdpur401.t_item
and tcibd001a.t_item = tisfc001.t_mitm
and (tdpur401.t_orno[1,3]='111' or tdpur401.t_orno[1,4]='1126' )
Attempt at T-SQL query:
from ttdpur401105 as tdpur401
inner join ttdpur400105 as tdpur400 on tdpur401.t_orno = tdpur400.t_orno
left outer join tarpur002105 as arpur002 on arpur002.t_orno = tdpur401.t_orno and arpur002.t_pono = tdpur401.t_pono
left outer join (ttdpur402105 as tdpur402
left outer join (ttisfc001105 as tisfc001
left outer join ttcibd001105 as tcibd001a on tcibd001a.t_item = tisfc001.t_mitm
and tisfc001.t_pdno = tdpur402.t_pdno) on tdpur402.t_orno = tdpur401.t_orno)
left outer join ttcibd001105 as tcibd001 on tcibd001.t_item = tdpur401.t_item
WHERE tdpur401.t_otbp = ' WD005'
and ((tdpur401.t_oltp=1 AND tdpur401.t_qibo <>0) OR(tdpur401.t_oltp=4 AND tdpur401.t_qibo = 0 AND tdpur401.t_qidl<>tdpur401.t_qoor))
and tdpur401.t_fire <> 1
and (tdpur400.t_hdst<>25 AND tdpur400.t_hdst<>30 AND tdpur400.t_hdst<>40)
and tdpur402.t_pono = tdpur402.t_pono
and substring(tdpur401.t_orno,1,3)='111' or substring(tdpur401.t_orno, 1,4)='1126'
Try this:
from ttdpur401105 as tdpur401
inner join ttdpur400105 as tdpur400 on tdpur401.t_orno = tdpur400.t_orno
left outer join tarpur002105 as arpur002
on arpur002.t_orno = tdpur401.t_orno and arpur002.t_pono = tdpur401.t_pono
left outer join ttdpur402105 as tdpur402
on tdpur402.t_orno = tdpur401.t_orno
left outer join ttisfc001105 as tisfc001
ON tisfc001.t_pdno = tdpur402.t_pdno
left outer join ttcibd001105 as tcibd001a
on tcibd001a.t_item = tisfc001.t_mitm
left outer join ttcibd001105 as tcibd001
on tcibd001.t_item = tdpur401.t_item
WHERE tdpur401.t_otbp = ' WD005'
and ((tdpur401.t_oltp=1 AND tdpur401.t_qibo <>0) OR(tdpur401.t_oltp=4 AND tdpur401.t_qibo = 0 AND tdpur401.t_qidl<>tdpur401.t_qoor))
and tdpur401.t_fire <> 1
and (tdpur400.t_hdst<>25 AND tdpur400.t_hdst<>30 AND tdpur400.t_hdst<>40)
and tdpur402.t_pono = tdpur402.t_pono
and substring(tdpur401.t_orno,1,3)='111' or substring(tdpur401.t_orno, 1,4)='1126'
And also you need to check this row:
and tdpur402.t_pono = tdpur402.t_pono
I'm a little confused about it.
Someone's naming conventions leave much to be desired. Also, a SELECT statement starts with SELECT; it feels funny looking at decapitated SQL. It looks like you've got the general idea right.
SELECT *
FROM ttdpur401105 AS tdpur401
JOIN ttdpur400105 AS tdpur400 ON tdpur401.t_orno = tdpur400.t_orno
LEFT JOIN tarpur002105 AS arpur002 ON arpur002.t_orno = tdpur401.t_orno
AND arpur002.t_pono = tdpur401.t_pono
LEFT JOIN ttcibd001105 AS tcibd001 ON tcibd001.t_item = tdpur401.t_item
LEFT JOIN (SELECT *
FROM ttdpur402105 AS tdpur402
LEFT JOIN (SELECT *
FROM ttisfc001105 AS tisfc001
LEFT JOIN ttcibd001105 AS tcibd001a
ON tcibd001a.t_item = tisfc001.t_mitm
)
ON tisfc001.t_pdno = tdpur402.t_pdno
)
ON tdpur402.t_orno = tdpur401.t_orno
AND tdpur402.t_pono = tdpur402.t_pono -- ??typo tdpur402.t_pono = tdpur401.t_pono
WHERE tdpur401.t_otbp = ' WD005'
AND ((tdpur401.t_oltp = 1 AND tdpur401.t_qibo <> 0) OR
(tdpur401.t_oltp = 4 AND tdpur401.t_qibo = 0 AND
tdpur401.t_qidl <> tdpur401.t_qoor))
AND tdpur401.t_fire <> 1
AND (tdpur401.t_orno[1,3]='111' OR tdpur401.t_orno[1,4]='1126' )
AND (tdpur400.t_hdst <> 25 AND tdpur400.t_hdst <> 30 AND tdpur400.t_hdst <> 40)
You might be able to write it without those inner SELECT parts, just using more LEFT JOIN notations. I think you'd need to use the parentheses to ensure the right interpretation (or, at the very least, I'd want to add the parentheses to explain to myself the interpretation).
The only issue left to worry about is that the old, non-standard Informix OUTER notation is not only syntactically different from the new, standard SQL notation but also produces different results under some circumstances. Most of the time, you'll be OK. But you should carefully scrutinize the results from your translated query to ensure that you get all the data you expect. On the whole, you're likely to find that the standard SQL produces what you want (and the old notation may have produced rows that you didn't actually want). But you must check carefully.
Clearly, I've not tested this code. You might need to tag the sub-selects with an AS clause, and that might have ramifications for the join conditions.
Having seen Andrey Gurinov's comment about the tdpur402.t_pono = tdpur402.t_pono condition, I agree with him that it is odd (I missed it until scanning his answer). It will evaluate to true unless tdpur402.t_pono is NULL. I suspect a typo; one of the two '402' should be '401', but that isn't guaranteed.

JOIN codition in SQL Server

After applying join condition on two tables I want records which is maximum among records of left table
My query
SELECT a1.*,
t.*,
( a1.trnratefrom - t.trnratefrom )AS minrate,
( a1.trnrateto - t.trnrateto ) AS maxrate
FROM (SELECT a.srno,
trndate,
b.trnsrno,
Upper(Rtrim(Ltrim(b.trnstate))) AS trnstate,
Upper(Rtrim(Ltrim(b.trnarea))) AS trnarea,
Upper(Rtrim(Ltrim(b.trnquality))) AS trnquality,
Upper(Rtrim(Ltrim(b.trnlength))) AS trnlength,
Upper(Rtrim(Ltrim(b.trnunit))) AS trnunit,
b.trnratefrom,
b.trnrateto,
a.remark,
entdate
FROM mstprodrates a
INNER JOIN trnprodrates b
ON a.srno = b.srno)a1
INNER JOIN (SELECT c.srno,
trndate,
d.trnsrno,
Upper(Rtrim(Ltrim(d.trnstate))) AS trnstate,
Upper(Rtrim(Ltrim(d.trnarea))) AS trnarea,
Upper(Rtrim(Ltrim(d.trnquality))) AS trnquality,
Upper(Rtrim(Ltrim(d.trnlength))) AS trnlength,
Upper(Rtrim(Ltrim(d.trnunit))) AS trnunit,
d.trnratefrom,
d.trnrateto,
c.remark,
entdate
FROM mstprodrates c
INNER JOIN trnprodrates d
ON c.srno = d.srno) AS t
ON a1.trnstate = t.trnstate
AND a1.trnquality = t.trnquality
AND a1.trnunit = t.trnunit
AND a1.trnlength = t.trnlength
AND a1.trnarea = t.trnarea
AND a1.remark = t.remark
WHERE t.srno = (SELECT MAX(srno)
FROM a1
WHERE srno < a1.srno)
If you mean to say,
you want Records exist in Left table but not in right then use LEFT OUTER JOIN.

Resources