Ниже мой запрос, но когда я включаю свои столбцы CapturedDateTime и IsOutOfSpec, он возвращает несколько строк, но я хочу, чтобы была возвращена только одна запись, которая отображает средние значения последних 10 записей. Таким образом, он должен возвращать средний вес детали, средний вес литника и средний вес заготовки для указанного кода запаса.

--Last 10 Average Report
SELECT Top 10 c.StockCode,i.LongDesc,
AVG(c.PartWeightGram) AS 'Part Weight Average',
AVG(c.SprueWeightGram) AS 'Sprue Weight Average' ,
AVG(c.TolerancePercentage) AS 'Tolerance Average' , 
AVG(c.BomWeightKG * 1000) AS 'Bom Weight Average' ,
AVG(c.PartWeightGram + (c.SprueWeightGram / 2)) - (c.BomWeightKG)  AS 'Variance To Syspro Average', 
AVG((((((c.PartWeightGram + c.SprueWeightGram  / 2))) - (c.BomWeightKG * 1000)) / (c.BomWeightKG * 1000))  * 100) AS 'VarianceToSysproPct'
FROM tblComponentWeightCheck c 
LEFT JOIN [Mercury].[EncoreCompanyA].dbo.InvMaster i ON  c.StockCode = i.StockCode
WHERE c.StockCode='000-256966-020' And Deleted = 'False'
GROUP BY c.StockCode,i.LongDesc,c.BomWeightKG
ORDER BY c.StockCode DESC

Это моя таблица:

SELECT [ComponentWeightCheckID]
      ,[EmpID]
      ,[StockCode]
      ,[Process]
      ,[PartWeightGram]
      ,[SprueWeightGram]
      ,[BomWeightKG]
      ,[TolerancePercentage]
      ,[AssetID]
      ,[CapturedDateTime]
      ,[Hostname]
      ,[Username]
      ,[IsOutOfSpec]
      ,[Tool]
      ,[Deleted]
  FROM [dbo].[tblComponentWeightCheck]

Пример данных:

SELECT  Top 10 c.StockCode,i.LongDesc AS 'Description', 
(SELECT  TOP 10 AVG(PartWeightGram) FROM tblComponentWeightCheck c WHERE c.StockCode = '000-256966-020' GROUP BY c.StockCode ) AS  'Part Weight Average',
(SELECT  TOP 10 AVG([SprueWeightGram]) FROM tblComponentWeightCheck c WHERE c.StockCode = '000-256966-020' GROUP BY c.StockCode  ) AS 'Sprue Weight Average',
(SELECT  TOP 10 AVG(c.TolerancePercentage) FROM tblComponentWeightCheck c WHERE c.StockCode = '000-256966-020' GROUP BY c.StockCode   ) AS 'Tolerance Average',
(SELECT  TOP 10 AVG([BomWeightKG]) FROM tblComponentWeightCheck c WHERE c.StockCode = '000-256966-020' GROUP BY c.StockCode   ) AS 'Bom Weight Average',
(SELECT  TOP 10 AVG((c.PartWeightGram + (c.SprueWeightGram / 2)) - (c.BomWeightKG * 1000)) FROM tblComponentWeightCheck c WHERE c.StockCode = '000-256966-020' GROUP BY c.StockCode   ) AS 'Variance To Syspro Average',
(SELECT  TOP 10 AVG((((((c.PartWeightGram + c.SprueWeightGram  / 2))) - (c.BomWeightKG * 1000)) / (c.BomWeightKG * 1000))  * 100) FROM tblComponentWeightCheck c WHERE c.StockCode = '000-256966-020' GROUP BY c.StockCode   ) AS 'Variance To Syspro & Average'                 
FROM tblComponentWeightCheck c
LEFT JOIN [Mercury].[EncoreCompanyA].dbo.InvMaster i ON  c.StockCode = i.StockCode
WHERE c.StockCode = '000-256966-020'
AND CONVERT(Date, c.CapturedDateTime) Between '2021-04-01' AND '2021-05-24'
GROUP BY c.StockCode, i.LongDesc

На этом изображении показан результат вышеуказанного запроса. Он возвращает только 1 строку, которая должна, но в ней отсутствуют столбцы CapturedDateTime И IsOutOfSpec, как только я включаю их, он возвращает несколько записей, которые мне не нужны.

0
coder101 8 Июн 2021 в 11:52

2 ответа

Лучший ответ

Предположительно, LEFT JOIN не нужен - было бы странно иметь коды акций, которых нет в мастере инвентаризации.

Вы можете легко сделать это, используя APPLY:

SELECT Top 10 i.StockCode, i.LongDesc,
       AVG(c.PartWeightGram) AS Part_Weight_Average,
       AVG(c.SprueWeightGram) AS Sprue_Weight_Average,
       AVG(c.TolerancePercentage) AS Tolerance_Average, 
       AVG(c.BomWeightKG * 1000) AS Bom_Weight_Average,
       AVG(c.PartWeightGram + (c.SprueWeightGram / 2)) - (c.BomWeightKG)  AS Variance_To_Syspro_Average, 
       AVG((((((c.PartWeightGram + c.SprueWeightGram  / 2))) - (c.BomWeightKG * 1000)) / (c.BomWeightKG * 1000))  * 100) AS VarianceToSysproPct
FROM [Mercury].[EncoreCompanyA].dbo.InvMaster i CROSS APPLY 
     (SELECT TOP (10) c.*
      FROM tblComponentWeightCheck c 
      WHERE c.StockCode = i.StockCode
      ORDER BY c.CapturedDateTime DESC
     ) c
WHERE i.StockCode = '000-256966-020' AND Deleted = 'False'
GROUP BY i.StockCode, i.LongDesc, c.BomWeightKG
ORDER BY i.StockCode DESC;

Для повышения производительности я рекомендую индексы на tblComponentWeightCheck(StockCode, CapturedDateTime DESC) и InvMaster(StockCode).

0
Gordon Linoff 8 Июн 2021 в 11:28

Судя по вашему запросу, вместо первой десятки следует использовать оконную функцию и подзапрос. По примеру. Однако вам нужно будет указать критерии сортировки для ROW_NUMBER (), чтобы определить «ТОП-10» ...

--Last 10 Average Report
SELECT c.StockCode,c.LongDesc,
AVG(c.PartWeightGram) AS 'Part Weight Average',
AVG(c.SprueWeightGram) AS 'Sprue Weight Average' ,
AVG(c.TolerancePercentage) AS 'Tolerance Average' , 
AVG(c.BomWeightKG * 1000) AS 'Bom Weight Average' ,
AVG(c.PartWeightGram + (c.SprueWeightGram / 2)) - (c.BomWeightKG)  AS 'Variance To Syspro Average', 
AVG((((((c.PartWeightGram + c.SprueWeightGram  / 2))) - (c.BomWeightKG * 1000)) / (c.BomWeightKG * 1000))  * 100) AS 'VarianceToSysproPct'
FROM (
  SELECT c.StockCode
    ,i.LongDesc
    ,c.PartWeightGram
    ,c.SprueWeightGram
    ,c.TolerancePercentage
    ,c.BomWeightKG
    ,c.PartWeightGram
    ,c.PartWeightGram
    ,ROW_NUMBER() OVER (PARTITION BY c.StockCode ORDER BY ...) AS rn
  FROM tblComponentWeightCheck c 
  LEFT JOIN [Mercury].[EncoreCompanyA].dbo.InvMaster i ON  c.StockCode = i.StockCode
  WHERE Deleted = 'False'
) c
WHERE c.StockCode='000-256966-020'
  AND rn <= 10
GROUP BY c.StockCode,c.LongDesc,c.BomWeightKG
ORDER BY c.StockCode DESC
0
Tyron78 8 Июн 2021 в 09:36