I am trying to modify a user query in order to return an extra column, INV1.WhsCode from the following SQL query:
SELECT T0.CardCode,
T2.CardName,
T0.CodeBars,
T0.ItemCode,
T0.ItemName,
T3.Price AS [POS Price],
T1.AvgPrice,
T1.OnHand,
T1.MinStock,
T1.MaxStock,
T0.NumInBuy AS Packsize,
T0.LstSalDate,
(
SELECT SUM(Quantity) AS Expr1
FROM dbo.INV1
INNER JOIN OINV
ON INV1.DocEntry = OINV.DocEntry
WHERE INV1.ItemCode = T0.ItemCode
AND INV1.WhsCode = [%2]
AND Month(OINV.DocDate) = month(GetDate())
) AS [Current Period],
(
SELECT SUM(Quantity) AS Expr1
FROM dbo.INV1
INNER JOIN OINV
ON INV1.DocEntry = OINV.DocEntry
WHERE INV1.ItemCode = T0.ItemCode
AND INV1.WhsCode = [%2]
AND Month(OINV.DocDate) = month(GetDate()) - 1
) AS [Previous Period],
(
SELECT SUM(Quantity) AS Expr1
FROM dbo.INV1
INNER JOIN OINV
ON INV1.DocEntry = OINV.DocEntry
WHERE INV1.ItemCode = T0.ItemCode
AND INV1.WhsCode = [%2]
AND Month(OINV.DocDate) = month(GetDate()) - 2
) AS [60-90],
(
SELECT TOP 1 OPDN.DocDate AS Expr1
FROM dbo.PDN1
INNER JOIN OPDN
ON PDN1.DocEntry = OPDN.DocEntry
WHERE PDN1.ItemCode = T0.ItemCode
ORDER BY OPDN.DocDate DESC
) AS LastGRNDate
FROM OITM T0
INNER JOIN OITW T1
ON T0.ItemCode = T1.ItemCode
INNER JOIN OCRD T2
ON T0.CardCode = T2.CardCode
INNER JOIN ITM1 T3
ON T0.ItemCode = T3.ItemCode
INNER JOIN OWHS T4
ON T1.WhsCode = T4.WhsCode
INNER JOIN OITB T5
ON T0.ItmsGrpCod = T5.ItmsGrpCod
WHERE T3.PriceList = '3'
AND T4.WhsName = [%0]
AND T5.ItmsGrpNam = [%1]
How do I achieve this? (MS SQL Server 2008)
There are a number of things wrong/inefficient about your query which I know you didn’t ask about, but I am going to answer anyway because it will help answer the question you did ask.
You need to avoid correlated subqueries where possible, there are times that they are unavoidable and the best solution, however I so often see them in a place where a JOIN would do the same job and the optimiser will deal with join so much better. For instance you have:
This evaluates the subquery for each row, whereas if you re-wrote as so:
you would get the same result, but evaluated in a much more efficent manner.
The next fault is your method of using
MONTH(GETDATE())– 1 to get 2 months ago. In January this will evauluate to 0 and get no matches. The best way to do this is to convert each date to the first of each month using something akin to his:The same principle of joins rather than correlated subqueries can also be applied to your quantity columns, and this gives access to the
WhsCodecolumns, it is not necessary, but I have used a common table expression to clean up the query (using the date logic from above)Combining all this into your final query gives:
This is all untested so there may be some typos/slight syntax errors, but the same principals should still apply.
If you are still set on the idea of correlated subqueries, you could use
APPLYto allow you to access multiple columns from it. e.g.