When I run a report for a purchase order, the report duplicates records for product codes.
For example the purchase order is: P000976, the report display the product code twice when it should only appear once. 45-5540 appears twice.
P000976 09-17-2012 15,040.00 15,040.00 0.00
45-5540 "Lordotic Cervical Spacer 10mm
Lordotic Cervical Spacer 10mm" 20 20 0
45-5540 "Lordotic Cervical Spacer 10mm
Lordotic Cervical Spacer 10mm" 20 20 0
When I put the report's SQL in SQL server and run the sql by seeing where the code cause the additional product code it is this line within the SQL:
join all_product_codes_VW p on q.distpartno = p.distpartno
select q.specialrequirement
, q.distpartno
, q.toproduce
, q.prodbegindate
, q.distributor
, rc.report_category_name
, s.productperpo
, r.ebi_released
, w.ebi_in_WIP
, p.distproductname
, tp.typeprefixdetail
, tp.cost
, '1' as ReportTotals
from all_required_vw q
left join all_shipped_grafts_new_VW s on (q.distpartno = s.distpartno and q.specialrequirement = s.ponumber)
left join all_released_Grafts_VW r on q.distpartno = r.distpartno
left join all_in_WIP_VW w on q.distpartno = w.distpartno
join all_product_codes_VW p on q.distpartno = p.distpartno
join setup_tissue_prefix tp on q.typenumber = tp.typeprefix
join setup_report_category_1 rc on q.distributor = rc.report_category_id
where q.prodbegindate < #enddate
and q.completed = '0'
and rc.report_category_name like '%' + isnull(#tcustomer, '') + '%'
order by q.prodbegindate, p.distproductname
This is the SQL for the view for which the join creates the duplicate.
SELECT COUNT_BIG(*) AS BIG, DistPartNo, DistProductName, Distributor, UMTBProductCode
FROM dbo.Setup_Distributor_Product_info
WHERE (Distributor <> '7') OR (Distributor IS NULL)
GROUP BY DistPartNo, DistProductName, Distributor, USSAProductCode
If you comment out these lines
--, p.distproductname
--join all_product_codes_VW p on q.distpartno = p.distpartno
Does the query return single rows for each distpartno? If yes then you're right that the all_products_code_VW view is causing the multiple rows.
Run these two queries and look at how many rows are in each and it will give you a clue as to why this is:
Select * from all_required_vw where distpartno = '45-5540'
Select * from all_product_codes_VW where distpartno = '45-5540'
My guess is that joining on only the distpartno is not enough to give you unique results. There might be more than one distributor for the same part, or multiple productnames for the same part number, e.g. different distrubutors using the the same part number with different products.
Possible this GROUP BY clause
GROUP BY DistPartNo, DistProductName, Distributor, USSAProductCode
need replace on this
GROUP BY DistPartNo, DistProductName, Distributor, UMTBProductCode
Related
I have an issue on my SQL query. I tried doing two ways
With the first query I got the right amount but I lose some name descriptions
With the second I got every name descriptions but I got a lower amount.
Context: I want to get the revenue gotten between two dates.
I need the following columns from tables
Table reciboDet I need the columns CtaIngreso, ValorUnitReciboDet
Table CuentaIngreso_A the column nombrectaingreso, ctaingreso (only to create the join)
Table Recibo the columns FechaRecibo and ReciboAnulado
To get the right name descriptions I need to verify the receipt year that was in the table AvpgEnc, but when I do that a lose the amount.
First query
SELECT
ReciboDet.CtaIngreso
, SUM(ReciboDet.ValorUnitReciboDet) AS Total
, CuentaIngreso_A.NombreCtaIngreso
FROM
ReciboDet
INNER JOIN CuentaIngreso_A
ON ReciboDet.CtaIngreso = CuentaIngreso_A.CtaIngreso
WHERE
(ReciboDet.NumRecibo IN
(SELECT NumRecibo
FROM Recibo
WHERE (FechaRecibo BETWEEN '01/10/2020' AND '31/10/2020')
AND (ReciboAnulado = 0)
AND (CuentaIngreso_A.Anio = DATEPART(year, FechaRecibo))
)
)
GROUP BY
ReciboDet.CtaIngreso
, CuentaIngreso_A.NombreCtaIngreso
ORDER BY
CuentaIngreso_A.NombreCtaIngreso
Second query
SELECT
ReciboDet.CtaIngreso [cuenta],
sum(ReciboDet.ValorUnitReciboDet) [monto],
CuentaIngreso_A.NombreCtaIngreso [descripcion]
FROM
ReciboDet
inner join avpgenc
on ReciboDet.NumFactura = AvPgEnc.NumAvPg
inner join CuentaIngreso_A
on ReciboDet.CtaIngreso = CuentaIngreso_A.CtaIngreso
WHERE
(ReciboDet.NumRecibo IN
(SELECT NumRecibo
FROM Recibo
WHERE (FechaRecibo BETWEEN '01/10/2020' AND '31/10/2020')
AND (ReciboAnulado = 0)
)
AND (year(AvPgEnc.FechaVenceAvPg) = CuentaIngreso_A.Anio)
)
GROUP BY
ReciboDet.CtaIngreso
, CuentaIngreso_A.NombreCtaIngreso
ORDER BY
ReciboDet.CtaIngreso
I have two tables that I need to combine, but I can't get to seem the joins to work. The picture has three tables
_date_array2: Has a field DateMonthYr that contains all possible date/yr combinations
_sales_summ_tbl__ => Has 5 fields. Only months with sales show up. For example, you see only three records showing up for the second table. There is no 5/2016, for example, because there were no sales for that month.
My goal is to "pad" the second table to have TotalDemand of 0's for months with no sales. I am very close (see the third table), except I cannot get the PartNumber to show up for dates with no sales.
My guess is that it's due to the RIGHT JOIN. But I'm not sure how to handle this. The output I am hoping for is table 3 but with the part number populated for all entries.
And here is my code (the results from running this code are the third/last table in the picture):
SELECT TmpSalesTbl.PartNumber as PartNumber,
tmp_date_array.CreateDateMonth as CreateDateMonth,
tmp_date_array.CreateDateYear as CreateDateYear,
CASE WHEN TmpSalesTbl.TotalDemand is NULL THEN 0 ELSE TmpSalesTbl.TotalDemand END as TotalDemand
FROM #_sales_summ_tbl__ TmpSalesTbl
RIGHT JOIN #_date_array2 tmp_date_array on tmp_date_array.CreateDateMonthYr = TmpSalesTbl.CreateDateMonthYr
ORDER BY tmp_date_array.CreateDateYear, tmp_date_array.CreateDateMonth
It is more conventional to place the list of all dates first, then left join to the data and whilst using a case expression is fine an alternative is coalesce(). This should ensure all the wanted months/years display:
SELECT
tmpsalestbl.PartNumber AS partnumber
, tmp_date_array.CreateDateMonth AS createdatemonth
, tmp_date_array.CreateDateYear AS createdateyear
, COALESCE(tmpsalestbl.TotalDemand, 0) AS totaldemand
FROM #_date_array2 tmp_date_array
LEFT JOIN #_sales_summ_tbl__ tmpsalestbl ON tmp_date_array.CreateDateMonthYr = tmpsalestbl.CreateDateMonthYr
ORDER BY
tmp_date_array.CreateDateYear
, tmp_date_array.CreateDateMonth
To populate for evey partnumber, on every month, you will need a new subquery:
select distinct PartNumber #_sales_summ_tbl__
And then cross join that to the years/months so you have a complete set of years/months/parts.
SELECT
cj.PartNumber AS partnumber
, tmp_date_array.CreateDateMonth AS createdatemonth
, tmp_date_array.CreateDateYear AS createdateyear
, COALESCE(tmpsalestbl.TotalDemand, 0) AS totaldemand
FROM #_date_array2 tmp_date_array
CROSS JOIN (
SELECT DISTINCT
PartNumber FROM #_sales_summ_tbl__
) cj
LEFT JOIN #_sales_summ_tbl__ tmpsalestbl ON tmp_date_array.CreateDateMonthYr = tmpsalestbl.CreateDateMonthYr
AND cj.PartNumber = tmpsalestbl.PartNumber
ORDER BY
tmp_date_array.CreateDateYear
, tmp_date_array.CreateDateMonth
;
I have set of two queries. In first query, if is separate from second, I got good results.
First query
SELECT *
FROM
(
SELECT nks.[Id]
, nks.[IdNarudzbe]
, nks.[IdArtikla] as artikal
, nks.[IdUsluge]
, nks.[Naziv]
, nks.Kolicina
, p.Naziv as kupac
, p.Id as kupacId
, p.Adresa
, p.Telefon
, nkz.[BrojDokumenta] AS nalog
, nkz.[BrojDokumentaKroz] AS nalogKroz
, nkz.[RokIsporuke]
, nkz.[IdNastaloOdDokumenta]
, d.Naziv as drzava
FROM [dbo].[NarudzbaKupacaStavke] nks
LEFT JOIN [dbo].[NarudzbeKupacaZaglavlje] nkz
ON nkz.Id = nks.IdNarudzbe
LEFT JOIN dbo.Partneri p
ON nkz.IdKupac = p.Id
LEFT JOIN dbo.Drzave d
ON p.IdDrzava = d.Id
WHERE idArtikla IN ('FP80PUR-08', 'FP80PUR-09', 'FP80PUR-12')
AND nkz.[VrstaDokumenta] = 'PRO'
AND nkz.StatusArhive = 0
--...
from first query nkz.[IdNastaloOdDokumenta] is important to second
SELECT BrojDokumenta
, BrojDokumentaKroz
FROM .[dbo].[NarudzbeKupacaZaglavlje]
where id = nkz.[IdNastaloOdDokumenta]
For ex. In first query I got nkz.[IdNastaloOdDokumenta] = 20. Number 20 I use in second query in where statement, and value I get from BrojDokumenta, I would like to join to first query.
I was wondering if is possible to make one query out of these two. I think I can not union operator because number of column from these two queries don't match.
The same table, and the same columns are already in the first query. Perhaps you want a self-join, like this:
FROM [dbo].[NarudzbaKupacaStavke] nks
LEFT JOIN [dbo].[NarudzbeKupacaZaglavlje] nkz
ON nkz.Id = nks.IdNarudzbe
LEFT JOIN [dbo].[NarudzbeKupacaZaglavlje] nkz2
ON nkz2.Id = nkz.[IdNastaloOdDokumenta]
LEFT JOIN dbo.Partneri p
ON nkz.IdKupac = p.Id
LEFT JOIN dbo.Drzave d
ON p.IdDrzava = d.Id
WHERE idArtikla IN ('FP80PUR-08', 'FP80PUR-09', 'FP80PUR-12')
AND nkz.[VrstaDokumenta] = 'PRO'
AND nkz.StatusArhive = 0
I had a query that was returning member transaction information. This query has an aggregate function to calculate the amount. All is working fine according to its grouping. Now what I need to do is to add two more columns from different tables. I did try to add them unfortunately they are giving me duplicated information with tons number of records.
Can anyone help me I just want to be able to include the two fields on the query and not include them in the group by clause. And also ensure that data returned is not a duplicate
See below is the query I used.
DECLARE #LastMonthExtractID Int = 11
SELECT x.*
,lstmnth.Submission ---added
,lm_subt.SubmissionTypeDescription ---added
FROM (
SELECT MemberRef --unique key
, SiteName
, ChargePeriod
, SUM(Amount) AS Amount
, TransactionMap
, PackageCode
FROM (
SELECT MemberRef
, SiteName
, ChargePeriod
, Amount
, PackageCode
, CASE WHEN map.TransactionMap = 'JoinFee' AND lstmnth.ChargeDate <> lstmnth.JoinDate THEN 'PayPlan'
WHEN map.TransactionMap = 'MemberFee' AND lstmnth.PackageCode LIKE 'PV%' AND lstmnth.SiteID <> 15 THEN 'VitalityMF' -- must use Package and not CURRENT PACKAGE
WHEN map.TransactionMap = 'MemberFee' AND lstmnth.PackageCode LIKE 'PV%' AND lstmnth.SiteID = 15 THEN 'PlatVitalityMF' -- PLATINUM
WHEN map.TransactionMap = 'MemberFee' AND lstmnth.PackageCode LIKE 'Z%' THEN 'ZContract'
WHEN map.TransactionMap IS NULL THEN 'Other'
ELSE map.TransactionMap END AS TransactionMap
--, lstmnth.Submission
--, lm_subt.SubmissionTypeDescription --added
FROM dbo.CCX_Billing lstmnth
LEFT JOIN dbo.TransactionMap map on lstmnth.TransactionType = map.TransactionType
AND lstmnth.TransactionDescription = map.TransactionDescription
AND ISNULL (lstmnth.AnalysisCode, '') = map.AnalysisCode
WHERE lstmnth.ExtractID = #LastMonthExtractID
) l
GROUP BY SiteName, MemberRef, ChargePeriod, PackageCode, TransactionMap
) x
INNER JOIN dbo.CCX_Billing lstmnth ON lstmnth.MemberRef = x.MemberRef
LEFT JOIN dbo.CCX_Billing_PSubmission lm_sub on lstmnth.SubmissionID = lm_sub.ID
INNER JOIN dbo.CCX_Billing_SubmissionType lm_subt on lm_sub.SubmissionTypeID = lm_subt.SubmissionID --added
I have a fairly complex sql that returns 2158 rows' id from a table with ~14M rows. I'm using CTEs for simplification.
The WHERE consists of two conditions. If i comment out one of them, the other runs in ~2 second. If i leave them both (separated by OR) the query runs ~100 seconds. The first condition alone needs 1-2 seconds and returns 19 rows, the second condition alone needs 0 seconds and returns 2139 rows.
What can be the reason?
This is the complete SQL:
WITH fpcRepairs AS
(
SELECT FPC_Row = ROW_NUMBER()OVER(PARTITION BY t.SSN_Number ORDER BY t.Received_Date, t.Claim_Creation_Date, t.Repair_Completion_Date, t.Claim_Submitted_Date)
, idData, Repair_Completion_Date, Received_Date, Work_Order, SSN_number, fiMaxActionCode, idModel,ModelName
, SP=(SELECT TOP 1 Reused_Indicator FROM tabDataDetail td INNER JOIN tabSparePart sp ON td.fiSparePart=sp.idSparePart
WHERE td.fiData=t.idData
AND (td.Material_Quantity <> 0)
AND (sp.SparePartName = '1254-3751'))
FROM tabData AS t INNER JOIN
modModel AS m ON t.fiModel = m.idModel
WHERE (m.ModelName = 'LT26i')
AND EXISTS(
SELECT NULL
FROM tabDataDetail AS td
INNER JOIN tabSparePart AS sp ON td.fiSparePart = sp.idSparePart
WHERE (td.fiData = t.idData)
AND (td.Material_Quantity <> 0)
AND (sp.SparePartName = '1254-3751')
)
), needToChange AS
(
SELECT idData FROM tabData AS t INNER JOIN
modModel AS m ON t.fiModel = m.idModel
WHERE (m.ModelName = 'LT26i')
AND EXISTS(
SELECT NULL
FROM tabDataDetail AS td
INNER JOIN tabSparePart AS sp ON td.fiSparePart = sp.idSparePart
WHERE (td.fiData = t.idData)
AND (td.Material_Quantity <> 0)
AND (sp.SparePartName IN ('1257-2741','1257-2742','1248-2338','1254-7035','1248-2345','1254-7042'))
)
)
SELECT t.idData
FROM tabData AS t INNER JOIN modModel AS m ON t.fiModel = m.idModel
INNER JOIN needToChange ON t.idData = needToChange.idData -- needs to change FpcAssy
LEFT OUTER JOIN fpcRepairs rep ON t.idData = rep.idData
WHERE
rep.idData IS NOT NULL -- FpcAssy replaced, check if reused was claimed correctly
AND rep.FPC_Row > 1 -- other FpcAssy repair before
AND (
SELECT SP FROM fpcRepairs lastRep
WHERE lastRep.SSN_Number = rep.SSN_Number
AND lastRep.FPC_Row = rep.FPC_Row - 1
) = rep.SP -- same SP, must be rejected(reused+reused or new+new)
OR
rep.idData IS NOT NULL -- FpcAssy replaced, check if reused was claimed correctly
AND rep.FPC_Row = 1 -- no other FpcAssy repair before
AND rep.SP = 0 -- not reused, must be rejected
order by t.idData
Here's the execution plan:
Download: http://www.filedropper.com/exeplanfpc
Try to use UNION ALL of 2 queries separately instead of OR condition.
I've tried it many times and it really helped. I've read about this issue in Art Of SQL .
Read it, you can find many useful information about performance issues.
UPDATE:
Check related questions
UNION ALL vs OR condition in sql server query
http://www.sql-server-performance.com/2011/union-or-sql-server-queries/
Can UNION ALL be faster than JOINs or do my JOINs just suck?
Check Wes's answer
The usage of the OR is probably causing the query optimizer to no longer use an index in the second query.