How to exclude duplicate values / NULL values SQL - sql

I hope that someone from you will be able to help me as I got stuck with a (silly) condition logic.
I am joining 2 temp tables.
The target is to see the Jobs, Tracking numbers, etc. (all actions) in one row always for one Consignee (Consignee Ref). In other words, to show all actions/data per Consignee Ref.
The issue I got is duplacated values. The problem is that the Original Job (620X) field can have assigned Tracking_1 but it can be also null. Also the Second Job (629X) filed can have but do not need to have assigned the Tracking number/value. It can be also the case that both Tracking_1 and Tracking are NULL for one Consignee Ref.
When I would exclude Jobs where Tracking_1 or Tracking is NULL, then I will loose the Jobs that have no Tracking Numbers at all. So I used the code below, but then I am getting duplicates.
SELECT * FROM #Temp t1
INNER JOIN #Temp2 t2 on t1.[Consignee Ref] = t2.[Consignee Ref]
WHERE t1.[Tracking_1] is not null
ORDER BY [Original Job (620X)] asc
How can I make it that I will get rid of the unnecessary duplicates (an example marked in red)?
And at the same time not to loose those jobs that have no Tracking Numbers?
I hope it makes sense.
Thank you very much in advance for any advise!
This is the entire code:
IF OBJECT_ID('tempdb..#Temp') IS NOT NULL
DROP TABLE #Temp;
SELECT distinct
cne.[Consignee Ref],
s.[Trial AWB] as [Original Job (620X)],
rl.[CarrierReference] as [Tracking_1],
CAST(st.[Sched Collection date] as date) AS [Collection Date],
CAST(st.[Act Del Date] as date) AS [Delivery Date],
s.[Clientaccountcode] as [Account Code]
into #Temp
FROM MKN_Reporting.dbo.shipment AS s WITH (NOLOCK)
LEFT JOIN MKN_Reporting.dbo.[Lookup Month By JN Tb] AS b WITH (NOLOCK) ON s.[id] = b.[JobId]
LEFT JOIN MKN_Reporting.dbo.[Lookup Branch currency Tb] AS c WITH (NOLOCK) ON b.BranchPrefix = c.[Branch Prefix]
LEFT JOIN MKN_Reporting.dbo.[Lookup Client group Tb] AS g WITH (NOLOCK) ON s.[Clientaccountcode] = g.[Customer A/c]
LEFT JOIN MKN_Reporting.dbo.[Chargeto] AS cg WITH (NOLOCK) ON s.[id] = cg.[jobid]
LEFT JOIN MKN_Reporting.dbo.[Shipper] AS sh WITH (NOLOCK) ON s.[id] = sh.[jobid]
LEFT JOIN MKN_Reporting.dbo.[Cnee] AS cne WITH (NOLOCK) ON s.[id] = cne.[jobid]
LEFT JOIN MKN_Reporting.dbo.[Lookup Country & Region Tb] AS r WITH (NOLOCK) ON sh.[Shipper Country code] = r.[Country Code]
LEFT JOIN MKN_Reporting.dbo.[Lookup Country & Region Tb] AS reg WITH (NOLOCK) ON cne.[Consignee Country code] = reg.[Country Code]
INNER JOIN MKN_Reporting.dbo.[Status] st ON COALESCE(s.ParentId, s.id) = st.Jobid
LEFT JOIN [CARRIERS_CHARGES] AS cc ON s.id = cc.JobId
LEFT JOIN [RouteLegs] as rl on cc.RouteLegId = rl.id
WHERE [Clientaccountcode] in ('US429', 'MI1091')
--AND rl.[CarrierReference] is not null
-------------------------------------------
IF OBJECT_ID('tempdb..#Temp2') IS NOT NULL
DROP TABLE #Temp2;
SELECT distinct
cne.[Consignee Ref],
s.[Study Number] as [Study_],
s.[Site Number] as [Site No_],
s.[Trial AWB] as [Second (629X)],
rl.[CarrierReference] as [Tracking],
CAST(st.[Sched Collection date] as date) AS [Collection Date],
CAST(st.[Act Del Date] as date) AS [Delivery Date],
s.[Clientaccountcode] as [Account Code]
into #Temp2
FROM MKN_Reporting.dbo.shipment AS s WITH (NOLOCK)
LEFT JOIN MKN_Reporting.dbo.[Lookup Month By JN Tb] AS b WITH (NOLOCK) ON s.[id] = b.[JobId]
LEFT JOIN MKN_Reporting.dbo.[Lookup Branch currency Tb] AS c WITH (NOLOCK) ON b.BranchPrefix = c.[Branch Prefix]
LEFT JOIN MKN_Reporting.dbo.[Lookup Client group Tb] AS g WITH (NOLOCK) ON s.[Clientaccountcode] = g.[Customer A/c]
LEFT JOIN MKN_Reporting.dbo.[Chargeto] AS cg WITH (NOLOCK) ON s.[id] = cg.[jobid]
LEFT JOIN MKN_Reporting.dbo.[Shipper] AS sh WITH (NOLOCK) ON s.[id] = sh.[jobid]
LEFT JOIN MKN_Reporting.dbo.[Cnee] AS cne WITH (NOLOCK) ON s.[id] = cne.[jobid]
LEFT JOIN MKN_Reporting.dbo.[Lookup Country & Region Tb] AS r WITH (NOLOCK) ON sh.[Shipper Country code] = r.[Country Code]
LEFT JOIN MKN_Reporting.dbo.[Lookup Country & Region Tb] AS reg WITH (NOLOCK) ON cne.[Consignee Country code] = reg.[Country Code]
INNER JOIN MKN_Reporting.dbo.[Status] st ON COALESCE(s.ParentId, s.id) = st.Jobid
LEFT JOIN [CARRIERS_CHARGES] AS cc ON s.id = cc.JobId
left JOIN [RouteLegs] as rl on cc.RouteLegId = rl.id
WHERE [Clientaccountcode] in ('US1598')
--AND rl.[CarrierReference] is not null
---------------------------------------------
SELECT * FROM #Temp t1
INNER JOIN #Temp2 t2 on t1.[Consignee Ref] = t2.[Consignee Ref]
WHERE t1.[Tracking_1] is not null
ORDER BY [Original Job (620X)] asc

I guess OP is looking for some kind of field aggregation for T2.
With SQL Server 2017+, like in PostgreSQL, you can now use STRING_AGG (same syntax than the Oracle LISTAGG.. "Why did they not use the same keyword...").
STRING_AGG will ignore null values from T2 and requires grouping if not alone. You have to add the other T1 and T2 required fields if any, but take care for T2 that it can imply duplicates and may need aggregation too...
Here is an example with your provided TSQL :
SELECT t1.[Consignee Ref], t1.[Original Job (620X)], t1.[Tracking_1],
STRING_AGG(t2.[Tracking],',') WITHIN GROUP (ORDER BY t2.[Tracking] ASC) Tracking_T2
FROM #Temp t1
INNER JOIN #Temp2 t2 on t1.[Consignee Ref] = t2.[Consignee Ref]
WHERE t1.[Tracking_1] is not null
GROUP BY t1.[Consignee Ref], t1.[Original Job (620X)], t1.[Tracking_1]
ORDER BY t1.[Original Job (620X)] asc
EDIT: For previous SQL Server release (before 2017), you can achieve string aggregation with XML query :
EDIT2: Adding EXISTS clause to convey the INNER JOIN from the initial query.
SELECT t1.[Consignee Ref], t1.[Original Job (620X)], t1.[Tracking_1],
STUFF((SELECT ', ' + t2.[Tracking]
FROM #Temp2 t2
WHERE t1.[Consignee Ref] = t2.[Consignee Ref]
ORDER BY t2.[Tracking]
FOR XML PATH('')), 1, 1, N'') Tracking_T2
FROM #Temp t1
WHERE t1.[Tracking_1] is not null
AND EXISTS (SELECT DISTINCT 1 FROM #Temp2 t2 WHERE t2.[Consignee Ref] = t1.[Consignee Ref])
GROUP BY t1.[Consignee Ref], t1.[Original Job (620X)], t1.[Tracking_1]
ORDER BY t1.[Original Job (620X)] asc

Related

Query to get the min date for the duplicate records

Below is my query, if there duplicate records I need to filter based on dates.
select
X.[po number],
(X.[ grn number]),
(X.[grn docentry]),
(X.ItemCode),
(X.[grn total]),
(X.tax),
(x.DocDate)[docdate]
from (
SELECT Distinct
T0.[DocNum] [po number],
T3.[DocNum] [ grn number],
T3.DocEntry [grn docentry],
T1.ItemCOde,
(T3.DocDate),
CASE WHEN T3.DocCur != 'SGD'
then (T4.PriceBefDi * T4.Quantity)
ELSE T4.LineTotal
END [grn total],
CASE WHEN T3.DocCur != 'SGD'
THEN T4.VatSumFrgn
ELSE T4.VatSum
END as [tax]
FROM OPOR T0
INNER JOIN POR1 T1 ON T0.DocEntry = T1.DocEntry
INNER JOIN PDN1 T4 on T1.DocEntry = T4.BaseEntry and T1.LineNum = T4.BaseLine
INNER JOIN OPDN T3 on T3.DocEntry = T4.DocEntry
)X
where X.[po number] in (37199, 37431, 37163, 37163, 37548)
and X.[grn total] in (1350.0000, 650.0000, 140.0000, 372.0000, 685.0000)
Below is my result set. if there are similar item codes, amount, tax amount. I need get only one record based on the minimum date for those matching. The highlighted red color must not show in the result set.
The actual output is like below:
You need to aggregate and select - what looks like - the min of each group:
select X.[po number], Min(X.[grn number])[grn number], Min(X.[grn docentry])[grn docentry], X.ItemCode, X.[grn total], X.tax, Min(X.DocDate) [docdate] from (
select distinct T0.[DocNum] [po number], T3.[DocNum] [ grn number], T3.DocEntry [grn docentry], T1.ItemCOde, T3.DocDate,
case when T3.DocCur != 'SGD' then (T4.PriceBefDi * T4.Quantity) else T4.LineTotal end [grn total] ,
case when T3.DocCur != 'SGD' then T4.VatSumFrgn else T4.VatSum end as [tax]
from OPOR T0
inner join POR1 T1 on T0.DocEntry = T1.DocEntry
inner join PDN1 T4 on T1.DocEntry = T4.BaseEntry and T1.LineNum = T4.BaseLine
inner join OPDN T3 on T3.DocEntry = T4.DocEntry
)X
where X.[po number] in (37199, 37431, 37163, 37163, 37548) and X.[grn total] in (1350.0000, 650.0000, 140.0000, 372.0000, 685.0000)
group by X.[po number], X.ItemCode, X.[grn total], X.tax
Use GROUP BY for and set HAVING clause MIN(x.DocDate).
I guess that your unique column is x.ItemCode and add the rest of column.
Sample:
GROUP BY x.ItemCode
HAVING MIN(x.DocDate)
One way is
select top(1) with ties *
from (
-- your original query
) t
order by row_number() over(partition by ItemCode, [grn total], tax order by docdate)

Multiplying 2 columns in sql but calculation is incorrect?

I have the following select statement:
SELECT c.compname AS [Company]
,e.empname AS [Employee Name]
,a.jobid AS [Job Number]
,a.JobNavn AS [Job Name]
,t.TName [Task Name]
,cu.DayDate AS [Booking Date]
,cu.HrsBooked AS [Scheduled Hours]
,x.Ressnavn AS [Client]
,tr.Sale
,SUM(cu.HrsBooked) * (tr.Sale) AS [Total]
FROM job a
INNER JOIN jobplan jp ON jp.JobId = a.jobid
INNER JOIN JobDimensions AS z ON z.jobid = a.jobid
INNER JOIN Ress AS x ON x.RessId = z.custid
INNER JOIN JobPrice AS y ON y.JobId = a.Jobid
INNER JOIN task t ON t.PlanId = jp.PlanId
INNER JOIN JobPriceactivity AS w ON w.priceId = y.priceId
INNER JOIN taskres tr ON tr.TaskId = t.TaskId
INNER JOIN emp e ON e.EmpId = tr.ResId
INNER JOIN comp c ON e.compid = c.compid
INNER JOIN CapUsed AS cu ON cu.RefId = tr.TaskResId
AND cu.RefType = 1
INNER JOIN arpaccount AS ar ON e.empname = ar.arpaccname
AND CAST(cu.DayDate AS DATE) BETWEEN #startdate
AND #enddate
WHERE e.EMPID >= '2'
AND cu.HrsBooked > '0'
GROUP BY c.compname
,e.empname
,a.jobid
,a.JobNavn
,t.TName
,cu.DayDate
,cu.HrsBooked
,x.Ressnavn
,y.priceid
,tr.Sale
But the calculation of my 'SUM' in the select is not correct as highlighted in yellow in the following extract
I was expecting something like the below highlighted in green:
Can anyone highlight where I am going wrong either in my main code or column sum?

SQL select statement that checks two columns and returns the value from a third [duplicate]

This question already has answers here:
SQL Server Error:"SQL Server Subquery returned more than 1 value"
(2 answers)
Closed 7 years ago.
I am writing a query that accesses multiple tables in the same database. For one of the columns in the select statement, I need to return
Table1.Column4
where Table1.Column = Table3.Column1 AND
Table1.Column2 = Table4.Column1
I have it written as:
SELECT AccNum.FieldValue
FROM PersonFieldValuesVW
INNER JOIN PersonFieldValuesVW AccNum
ON AccNum.PersonId = InPerson.PersonId
INNER JOIN InPerson
ON InPerson.IncidentId = Incident.Id
WHERE AccNum.FieldDescr like '%Account Number%') as [Account Number],
This is returning the error:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Here is the full query, any assistance would be appreciated.
SELECT DISTINCT
CaseNum as [Case Number],
ALCategoryVW.Category as [Category],
ALCategoryVW.SubCategory as [Sub Category],
InAssign.AssignToName as [Assigned To],
ReportedDate as [Open Date],
EndDate as [Closed Date], --This a placeholder for a closed date
[Status],
SiteLoc1.Descr as [Loss Location],
LocDetails as [Loss Cost Center],
SiteLoc1.Region as [Region],
SiteLoc1.SubRegion as [Sub Region],
-- SiteLoc2.Descr as [Location Description], **Need this though returning all for the location?
CASE WHEN SAR.FieldId = '604NU' and SAR.FieldValue <> 'False' THEN 'YES' ELSE 'NO' END as [SAR Required],
Summary as [Incident Summary],
Disposition as [Case Disposition],
(
SELECT AccNum.FieldValue
FROM PersonFieldValuesVW
INNER JOIN PersonFieldValuesVW AccNum ON AccNum.PersonId = InPerson.PersonId
INNER JOIN InPerson ON InPerson.IncidentId = Incident.Id
WHERE AccNum.FieldDescr like '%Account Number%'
) as [Account Number],
FORMAT(AuditItemDetail.ItemValue, '#,###') as [Potential Loss],
FORMAT(AuditItemDetail.ItemValue - AuditItemDetail.PreventedExposureAmount, '#,###') as [Actual Loss]
FROM Incident
INNER JOIN ALCategoryVW ON ALCategoryVW.IncidentId = Incident.Id
INNER JOIN InAssign ON InAssign.IncidentId = Incident.Id
INNER JOIN SiteLoc1 ON SiteLoc1.Id = Incident.LocId
INNER JOIN SiteLoc2 ON SiteLoc2.SiteLoc1Id = SiteLoc1.Id
INNER JOIN IncidentFieldValuesVW SAR ON SAR.IncidentId = Incident.Id
INNER JOIN InItem ON InItem.IncidentId = Incident.Id
INNER JOIN AuditItemDetail ON AuditItemDetail.ItemId = InItem.ItemId
INNER JOIN InPerson ON InPerson.IncidentId = Incident.Id
INNER JOIN PersonFieldValuesVW AccNum ON AccNum.PersonId = InPerson.PersonId
This should resolve your error, but I'm not sure it is logically correct. If you have two records being returned in the sub-select, which one is the "right" one.
SELECT DISTINCT
CaseNum as [Case Number],
ALCategoryVW.Category as [Category],
ALCategoryVW.SubCategory as [Sub Category],
InAssign.AssignToName as [Assigned To],
ReportedDate as [Open Date],
EndDate as [Closed Date], --This a placeholder for a closed date
[Status],
SiteLoc1.Descr as [Loss Location],
LocDetails as [Loss Cost Center],
SiteLoc1.Region as [Region],
SiteLoc1.SubRegion as [Sub Region],
-- SiteLoc2.Descr as [Location Description], **Need this though returning all for the location?
CASE WHEN SAR.FieldId = '604NU' and SAR.FieldValue <> 'False' THEN 'YES' ELSE 'NO' END as [SAR Required],
Summary as [Incident Summary],
Disposition as [Case Disposition],
AccNum.FieldValue,
FORMAT(AuditItemDetail.ItemValue, '#,###') as [Potential Loss],
FORMAT(AuditItemDetail.ItemValue - AuditItemDetail.PreventedExposureAmount, '#,###') as [Actual Loss]
FROM Incident
INNER JOIN ALCategoryVW ON ALCategoryVW.IncidentId = Incident.Id
INNER JOIN InAssign ON InAssign.IncidentId = Incident.Id
INNER JOIN SiteLoc1 ON SiteLoc1.Id = Incident.LocId
INNER JOIN SiteLoc2 ON SiteLoc2.SiteLoc1Id = SiteLoc1.Id
INNER JOIN IncidentFieldValuesVW SAR ON SAR.IncidentId = Incident.Id
INNER JOIN InItem ON InItem.IncidentId = Incident.Id
INNER JOIN AuditItemDetail ON AuditItemDetail.ItemId = InItem.ItemId
INNER JOIN InPerson ON InPerson.IncidentId = Incident.Id
LEFT JOIN PersonFieldValuesVW AccNum ON AccNum.PersonId = InPerson.PersonId AND AccNum.FieldDescr like '%Account Number%'
***Updated based on comment.

SQL - query to report MAX DATE results or NULL results

I have an SQL database with 3 tables:
Customer record table, holding master data (each row is unique)
Customer notes, each note data/time stamped (there could be many notes per customer, or none at all)
Product table, showing which customer has bought which product
Table: tbl_Customer_Records
CustomerID---- Company Name-----Company Segment----- Promo Code
Table: tbl_Customer_Notes
CustomerID---- Note-----Created Date
Table: tbl_Customer_Products
CustomerID---- Product Category
What I want is to pull a list of customer records which includes the latest note only, so there are no duplicate lines if multiple notes exist. But I also want my report to include customer records if no notes exist at all. I've achieved the first part of this with a SELECT MAX function, and that works well, the problem is when I add the OR = NULL clause in the final line of code below. This doesn't work, and I can't figure out a solution.
Any suggestions will be greatly appreciated!
SELECT
[tbl_Customer_Records].[CustomerID],
[tbl_Customer_Records].[Company Name],
[tbl_Customer_Records].[Company Segment],
[tbl_Customer_Records].[Promo Code],
[tbl_Customer_Notes].[Note],
[tbl_Customer_Products].[Product Category]
FROM
tbl_Customer_Records
LEFT OUTER JOIN tbl_Customer_Notes
ON tbl_Customer_Records.CustomerID = tbl_Customer_Notes.CustomerID
LEFT OUTER JOIN tbl_Customer_Products
ON tbl_Customer_Records.CustomerID = tbl_Customer_Products.CustomerID
WHERE
[Product Category] in ('Nuts','Bolts','Screws','Spanners')
AND
[Created Date] in (SELECT MAX ([Created Date]) FROM tbl.Customer_Notes GROUP BY [CustomerID])
OR tbl_Customer_Note.Note is null
There're a few tricks to do this kind of query (row_number or join with grouped data), but I think most cleanest one in your case is to use outer apply:
select
cr.[CustomerID],
cr.[Company Name],
cr.[Company Segment],
cr.[Promo Code],
cn.[Note],
cp.[Product Category]
from tbl_Customer_Records as cr
left outer join tbl_Customer_Products as cp on cp.CustomerID = cr.CustomerID
outer apply (
select top 1
t.[Note]
from tbl_Customer_Notes as t
where t.[CustomerID] = cr.[CustomerID]
order by t.[Created_Date] desc
) as cn
where
cp.[Product Category] in ('Nuts','Bolts','Screws','Spanners')
Changed all clumsy table name.column name to alias.column name, I think it's much more readable this way.
Or:
select
cr.[CustomerID],
cr.[Company Name],
cr.[Company Segment],
cr.[Promo Code],
cn.[Note],
cp.[Product Category]
from tbl_Customer_Records as cr
left outer join tbl_Customer_Products as cp on cp.CustomerID = cr.CustomerID
left outer join tbl_Customer_Notes as cn on
cn.CustomerID = cr.CustomerID and
cn.[Created_Date] = (select max(t.[Created_Date]) from tbl_Customer_Notes as t where t.CustomerID = cr.CustomerID)
where
cp.[Product Category] in ('Nuts','Bolts','Screws','Spanners')
You can add your filter condition in ON predicate to preserve rows from left table and fetch only required matching rows from right table, from first LEFT OUTER JOIN operator. Following query should work:
SELECT
CR.[CustomerID],
CR.[Company_Name],
CR.[Company_Segment],
CR.[Promo_Code],
CN.[Note],
CP.[Product_Category]
FROM
tbl_Customer_Records CR
LEFT OUTER JOIN tbl_Customer_Notes CN
ON CR.CustomerID = CN.CustomerID AND CN.[Created_Date] in (SELECT MAX ([Created_Date])
FROM tbl_Customer_Notes
WHERE CR.CustomerID = tbl_Customer_Notes.CustomerID
GROUP BY [CustomerID])
LEFT OUTER JOIN tbl_Customer_Products CP
ON CR.CustomerID = CP.CustomerID
WHERE
[Product_Category] in ('Nuts','Bolts','Screws','Spanners')
Should work, tried with NULL values:
SELECT a.[CustomerID],
a.[Company Name],
a.[Company Segment],
a.[Promo Code],
a.[Note],
a.[Product Category]
FROM (
SELECT
cr.[CustomerID],
cr.[Company Name],
cr.[Company Segment],
cr.[Promo Code],
cn.[Note],
cp.[Product Category],
ROW_NUMBER() OVER(PARTITION BY cr.[CustomerID] ORDER BY cn.[Created Date] DESC) as rnk
FROM tbl_Customer_Records cr
LEFT JOIN tbl_Customer_Notes cn
ON cr.CustomerID = cn.CustomerID
LEFT JOIN tbl_Customer_Products cp
ON cr.CustomerID = cp.CustomerID
WHERE cp.[Product Category] in ('Nuts','Bolts','Screws','Spanners') )a
WHERE a.rnk = 1
try to use CustomerID not in (select CustomerID from tbl_Customer_Note)

Consolidating Queries

I'm trying to understand how to combine queries when one of them returns more than one record.
This is an invoicing report where I want to pull in the Serial Numbers of products invoiced. I'll abbreviate the script as much as possible to clarify. Here is my script before adding the serials:
SELECT ARM.fcustno AS [Cust No]
, ARM.fbcompany AS [Cust Name]
, ARM.fcinvoice AS [Invoice No]
, ARM.fdgldate AS [Post Date]
, ARI.fitem AS [Item No]
, ARI.fprodcl AS [Prod Class]
, ARI.fshipkey AS [Qty Invoiced]
, ARI.fpartno AS [Part No]
, ARI.frev AS [Part Rev]
, ARI.FTOTPRICE AS [Net Invoiced]
, ARM.fsono AS [Sales No]
, SOM.fcusrchr2
FROM dbo.armast ARM
INNER JOIN dbo.aritem ARI ON ARM.FCINVOICE = ARI.FCINVOICE
INNER JOIN slcdpm SLC ON SLC.fcustno = ARM.fcustno
LEFT OUTER JOIN slcdpm_ext SLCE ON SLC.identity_column = SLCE.fkey_id
LEFT OUTER JOIN somast SOM ON SOM.fsono = ARM.fsono
This returns invoiced line items, their prices, and such. When I pull in the following:
SELECT ARM.fcustno AS [Cust No]
, ARM.fbcompany AS [Cust Name]
, ARM.fcinvoice AS [Invoice No]
, ARM.fdgldate AS [Post Date]
, ARI.fitem AS [Item No]
, ARI.fprodcl AS [Prod Class]
, ARI.fshipkey AS [Qty Invoiced]
, ARI.fpartno AS [Part No]
, ARI.frev AS [Part Rev]
, ARI.FTOTPRICE AS [Net Invoiced]
, ARM.fsono AS [Sales No]
, SOM.fcusrchr2
, LOTC.fcuseinlot
FROM dbo.armast ARM
INNER JOIN dbo.aritem ARI ON ARM.FCINVOICE = ARI.FCINVOICE
INNER JOIN slcdpm SLC ON SLC.fcustno = ARM.fcustno
LEFT OUTER JOIN slcdpm_ext SLCE ON SLC.identity_column = SLCE.fkey_id
LEFT OUTER JOIN somast SOM ON SOM.fsono = ARM.fsono
--** New stuff below: ******
LEFT OUTER JOIN ShItem SHI ON SHI.fShipNo + SHI.fItemNo = ARI.fShipKey
LEFT OUTER JOIN ShSrce ON ShSrce.fcShipNo = SHI.fShipNo
AND ShSrce.fcItemNo = SHI.fItemNo
LEFT OUTER JOIN QaLotC LOTC ON LOTC.fcUseInDoc = ShSrce.fcShipNo + ShSrce.fcItemNo + ShSrce.fcSrcItmNo
The problem is that there can be multiple SHSRCE records per invoice. What is the best way to handle this? Perhaps use a subquery to concatenate the LOTC.fcuseinlot field in order to return one corresponding value per record.
To clarify, the additional query returns more than 1 record per line item invoice because multiple serial number parts can be invoiced on one line item. Ideally, I'd like them to be concatenated like (NCC1701, R2D2, C3PO) etc. That's why I thought about using a subquery to concatenate them.
Still waiting for the OP to clarify the question, but if the multiple SHSRCE records still only relate to one serialnumber (which i am presuming is in LOTC.fcuseinlot)
SELECT
ARM.fcustno AS [Cust No] ,
ARM.fbcompany AS [Cust Name] ,
ARM.fcinvoice AS [Invoice No] ,
ARM.fdgldate AS [Post Date] ,
ARI.fitem AS [Item No] ,
ARI.fprodcl AS [Prod Class] ,
ARI.fshipkey AS [Qty Invoiced] ,
ARI.fpartno AS [Part No] ,
ARI.frev AS [Part Rev] ,
ARI.FTOTPRICE AS [Net Invoiced] ,
ARM.fsono AS [Sales No] ,
SOM.fcusrchr2,
MAX(LOTC.fcuseinlot)
FROM
dbo.ARMAST ARM
JOIN dbo.aritem ARI ON ARI.FCINVOICE = ARM.FCINVOICE
JOIN slcdpm SLC ON SLC.fcustno = ARM.fcustno
LEFT JOIN slcdpm_ext SLCE ON SLCE.fkey_id = SLC.identity_column
LEFT JOIN somast SOM ON SOM.fsono = ARM.fsono
LEFT JOIN ShItem SHI ON SHI.fShipNo + SHI.fItemNo = ARI.fShipKey
LEFT JOIN ShSrce ON ShSrce.fcShipNo = SHI.fShipNo AND ShSrce.fcItemNo = SHI.fItemNo
LEFT JOIN QaLotC LOTC ON LOTC.fcUseInDoc = ShSrce.fcShipNo + ShSrce.fcItemNo + ShSrce.fcSrcItmNo
GROUP BY
ARM.fcustno ,
ARM.fbcompany ,
ARM.fcinvoice ,
ARM.fdgldate ,
ARI.fitem ,
ARI.fprodcl ,
ARI.fshipkey ,
ARI.fpartno ,
ARI.frev ,
ARI.FTOTPRICE ,
ARM.fsono ,
SOM.fcusrchr2
can you post some sample data.
If I'm getting you right, take a look at this kind of sql
create table tableA (id int, ref varchar(50))
insert into tableA
select 1, 3536757616
union select 1, 3536757617
union select 1, 3536757618
union select 2, 3536757628
union select 2, 3536757629
union select 2, 3536757630
I know I can simply concatenate the refs by using
SELECT distinct
id,
stuff ( ( SELECT
'/ ' + ref
FROM
tableA tableA_1
where tableA_1.id = tableA_2.id
FOR XML PATH ( '' ) ) , 1 , 2 , '' )
from TableA tableA_2
to give
1 3536757616/ 3536757617/ 3536757618
2 3536757628/ 3536757629/ 3536757630
Combine queries? As in do a UNION?
What we really need to know is what basis are you going to use to choose which of the possible records has the values you want returned? That will determine the best possibilites for you.
And as you aren't adding any columns and you are using left joins (so no records will be excluded from the joins) what is it you expect to accomplish by adding these joins except to lengthen processing time?
You've got a SQL Server 2000 tag on your question, so I'm not sure this is going to be possible for you. In SQL Server 2005 and above, you can create custom aggregate functions. I use an aggregate function FormDelimitedString, which does exactly what you are looking for.
There is a page here which describes how to implement this function - it gets written as a .NET assembly and then executed from within your queries. With this in place, your query becomes...
SELECT ARM.fcustno AS [Cust No]
, ARM.fbcompany AS [Cust Name]
-- (a few fields skipped for brevity)
, SOM.fcusrchr2
-- Aggregate function will combine multiple values into a single string - 'value1, value2, value3' etc
, dbo.FormDelimitedString(LOTC.fcuseinlot) AS ConcatenatedValues
FROM dbo.armast ARM
INNER JOIN dbo.aritem ARI ON ARM.FCINVOICE = ARI.FCINVOICE
INNER JOIN slcdpm SLC ON SLC.fcustno = ARM.fcustno
LEFT OUTER JOIN slcdpm_ext SLCE ON SLC.identity_column = SLCE.fkey_id
LEFT OUTER JOIN somast SOM ON SOM.fsono = ARM.fsono
LEFT OUTER JOIN ShItem SHI ON SHI.fShipNo + SHI.fItemNo = ARI.fShipKey
LEFT OUTER JOIN ShSrce ON ShSrce.fcShipNo = SHI.fShipNo
AND ShSrce.fcItemNo = SHI.fItemNo
LEFT OUTER JOIN QaLotC LOTC ON LOTC.fcUseInDoc = ShSrce.fcShipNo + ShSrce.fcItemNo + ShSrce.fcSrcItmNo
-- Group by clause needed as its an aggregate function
GROUP BY ARM.fcustno, ARM.fbcompany, SOM.fcusrchr2