SAP b1 Query date input not working with join - sql

I am trying to pull invoice data from 2 tables OINV and INV1. I need the query to give me results for a specified date range. Here is my query:
SELECT T0."DocDate", T0."NumAtCard", T0."CardName", T1."ItemCode", T1."Quantity", T1."Price", T0."DocTotal"
FROM "OINV" T0 LEFT JOIN
INV1 T1
ON T0."DocEntry" = T1."DocEntry"
WHERE T0."CANCELED" = 'N', T0."DocDate" >=[%0] AND T0."DocDate" <=[%1]
This doesn't ask for the date input when I execute it and doesn't return anything. The date input works fine when I use the OINV table alone, but doesn't when I do the join. Any ideas why this is happening?

Add this before your code
/*SELECT * FROM OINV T0*/
declare #FromDate date
declare #ToDate date
/* WHERE */
set #FromDate = /* T0.DocDate */‘[%0]’
set #ToDate =/* T0.DocDate */ ‘[%1]’

the query :
SELECT T0."DocDate", T0."NumAtCard", T0."CardName", T1."ItemCode", T1."Quantity", T1."Price", T0."DocTotal"
FROM "OINV" T0 LEFT JOIN
INV1 T1
ON T0."DocEntry" = T1."DocEntry"
WHERE T0."CANCELED" = 'N' AND T0."DocDate" >=[%0] AND T0."DocDate" <=[%1]
Works Fine on my System
remove the "," and add "AND"

Remove the "" in all your columns.
SELECT T0.DocDate, T0.NumAtCard, T0.CardName, T1.ItemCode, T1.Quantity, T1.Price, T0.DocTotal
FROM OINV T0 LEFT JOIN
INV1 T1
ON T0.DocEntry = T1.DocEntry
WHERE T0.CANCELED = 'N' AND T0.DocDate >=[%0] AND T0.DocDate <=[%1]

Related

How to find 10 items that sold the most in the last year?

I need a list of the top 10 best selling items in the last year.
I am required to use dateadd.
In my opinion, fromdate and dateto should also be used, but I didn't succeed.
I would appreciate your help
SELECT
RDR1.ItemCode [Itemcode],
RDR1.Quantity [Quantity],
YEAR(RDR1.DocDate) [DocDate]
FROM
ORDR
INNER JOIN
RDR1 ON ORDR.DocEntry = RDR1.DocEntry
WHERE
RDR1.DocDate BETWEEN (#date) AND (YEAR(GETDATE())- 1)
-- RDR1.DocDate BETWEEN (#DateTo) AND (#date)
GROUP BY
(RDR1.ItemCode)
ORDER BY
SUM(RDR1.Quantity) DESC
SELECT TOP 20 T1.ItemCode, T2.ItemName, cast(sum(T1.Quantity) as numeric) as 'Quantity Sold', sum(T1.LineTotal - T1.VatSum) as 'Total Net Value', sum(T1.LineTotal) as 'Total Gross Value', T1.Currency
FROM dbo.INV1 T1 inner join OINV T3 on T1.docentry = t3.docentry
LEFT OUTER JOIN OITM T2 on T1.ItemCode = T2.ItemCode INNER JOIN OCRD T4 ON T2.CardCode = T4.CardCode INNER JOIN OCRG T5 ON T4.GroupCode = T5.GroupCode
WHERE T1.ItemCode is not null and (t3.docdate between [%0] and [%1]) and t3.series = 229 and T5.GroupName = '[%2]'
GROUP BY T1.ItemCode, T2.ItemName, T1.Currency
order by sum(T1.Quantity) desc
Hope this helps :)

How can code User input parameter from first date to last date (SQL query manager)

I need help, I write the code and have to use The Last Date from user parameter >> [%1] in statement
but when I execute ..the filled window force me fill from the last date to first date. It should be fill from the first date to last date.
when I execute... the "User window" popup and need to input date from the first date to last date (ex: 01/08/20 - 30/09/20) but from the fact from above coding,
user have to input the last date to the first date (ex: 30/09/20 - 01/08/20) << this will make user confuse
I attached the pic for you can see it clear>>
Select
T0.docnum , T0.docdate , Sum(T1.Quantity),
Sum(case when T0.docdate between dateadd(month,0,DATEADD(DAY,1-DATEPART(day,'[%1]'),'[%1]')) and eomonth(dateadd(month,0,DATEADD(DAY,1-DATEPART(day,'[%1]'),'[%1]'))) then T1.Quantity*T2.U_hmc_vollts else 0 end) as 'm12_Lts' ,
sum(case when T0.docdate between dateadd(month,-1,DATEADD(DAY,1-
DATEPART(day,'[%1]'),'[%1]')) and eomonth(dateadd(month,-1,DATEADD(DAY,1-
DATEPART(day,'[%1]'),'[%1]'))) then T1.Quantity*T2.U_hmc_vollts else 0 end) as 'm11_Lts'
From OINV T0
left join inv1 T1 on T0.DocEntry = T1.DocEntry
left join oitm T2 on T1.ItemCode = T2.ItemCode
Where
T0.docdate >= '[%0]' and T0.Docdate <= '[%1]'
Group By
T0.docnum, T0.Docdate
Try Inserting
/*SELECT FROM [dbo].[OWTR] p1*/
declare #FROM as Datetime
declare #TO as datetime
/* WHERE */
set #FROM = /* p1.docdate */ '[%0]'
set #TO = /* p1.docdate */ '[%1]'
at the top of your query (the table doesn't really matter)
then replace the [%0] with #FROM and [%1] with #TO in the rest of your query.
Full Code:
/*SELECT FROM [dbo].[OWTR] p1*/
declare #FROM as Datetime
declare #TO as datetime
/* WHERE */
set #FROM = /* p1.docdate */ '[%0]'
set #TO = /* p1.docdate */ '[%1]'
Select
T0.docnum , T0.docdate , Sum(T1.Quantity),
Sum(case when T0.docdate between dateadd(month,0,DATEADD(DAY,1-
DATEPART(day,#TO),#TO)) and eomonth(dateadd(month,0,DATEADD(DAY,1-
DATEPART(day,#TO),#TO))) then T1.Quantity*T2.U_hmc_vollts else 0 end) as
'm12_Lts' ,
sum(case when T0.docdate between dateadd(month,-1,DATEADD(DAY,1-
DATEPART(day,#TO),#TO)) and eomonth(dateadd(month,-1,DATEADD(DAY,1-
DATEPART(day,#TO),#TO))) then T1.Quantity*T2.U_hmc_vollts else 0 end) as
'm11_Lts'
From OINV T0
left join inv1 T1 on T0.DocEntry = T1.DocEntry
left join oitm T2 on T1.ItemCode = T2.ItemCode
Where
T0.docdate >= #FROM and T0.Docdate <= #TO
Group By
T0.docnum, T0.Docdate
let me know how you get on.
Add order by to your SQL statement.
https://learn.microsoft.com/en-us/sql/t-sql/queries/select-order-by-clause-transact-sql?view=sql-server-ver15

Problem with merging two SELECTS (One of them is PIVOT)

I'm newbie in SQL but I'm trying to do some stuff. I wanted to make some queries in sap sql. I done two.
1st:
SELECT
OINV.DocEntry,
OINV.DocNum AS N'FV',
OITM.ItemCode,
OITM.ItemName,
CAST(T1.Ilosc AS int) AS N'Sum',
T1.unitMsr AS N'UoM',
T1.[Price Min],
T1.Currency AS N'PLN',
T1.DocDate AS N'Last'
FROM
OITM
INNER JOIN
(
SELECT
OINV.CardCode,
MAX(OINV.DocDate) AS DocDate,
MAX(OINV.DocEntry) AS DocEntry,
INV1.ItemCode,
SUM(INV1.Quantity) AS Ilosc,
INV1.unitMsr,
MIN(INV1.Price) AS 'Price Min',
INV1.Currency
FROM OINV inner join INV1 ON OINV.DocEntry = INV1.DocEntry
WHERE INV1.ItemCode is not null
GROUP BY OINV.CardCode, INV1.ItemCode, INV1.unitMsr, INV1.Currency
) AS T1 ON OITM.ItemCode = T1.ItemCode
INNER JOIN OINV ON OINV.DocEntry = T1.DocEntry
WHERE T1.CardCode = N'OT-05453' AND T1.ItemCode NOT IN (SELECT DISTINCT U_ItemCode FROM [#BP2] WHERE U_CardCode = N'OT-05453' )
ORDER BY IIF(OITM.QryGroup1 = 'Y', 'Tak', '') desc, T1.DocDate, ItemCode
And 2nd one:
SELECT
P.ItemCode,
[2017] [2017],
[2018] [2018],
[2019] [2019]
FROM
(SELECT
INV1.ItemCode,
OINV.CardCode as C,
INV1.Quantity Volume,
year(INV1.[DocDate]) as year
FROM INV1 INNER JOIN OINV ON INV1.docentry = OINV.docentry
WHERE INV1.[docDate] between year(2007) and GETDATE() AND OINV.cardcode = N'OT-05453'
) S
Pivot
(sum([volume]) For year IN ([2017],[2018],[2019])) P
Both works correctly.
But I want to merge them. Both selects has same itemcodes. Just wanted to add 2nd query results on the right.
I was trying to use UNION but it wasn't working.
Hope that you will show me right way :)
The results of both queries produces some tables. You can put in brackets each query and join them using Itemcode column from both queries. Something like below:
SELECT t1.*, t2.[2017], t2.[2018], t2.[2019]
FROM
(
SELECT
OINV.DocEntry,
OINV.DocNum AS N'FV',
OITM.ItemCode,
OITM.ItemName,
CAST(T1.Ilosc AS int) AS N'Sum',
T1.unitMsr AS N'UoM',
T1.[Price Min],
T1.Currency AS N'PLN',
T1.DocDate AS N'Last'
FROM
OITM
INNER JOIN
(
SELECT
OINV.CardCode,
MAX(OINV.DocDate) AS DocDate,
MAX(OINV.DocEntry) AS DocEntry,
INV1.ItemCode,
SUM(INV1.Quantity) AS Ilosc,
INV1.unitMsr,
MIN(INV1.Price) AS 'Price Min',
INV1.Currency
FROM OINV inner join INV1 ON OINV.DocEntry = INV1.DocEntry
WHERE INV1.ItemCode is not null
GROUP BY OINV.CardCode, INV1.ItemCode, INV1.unitMsr, INV1.Currency
) AS T1 ON OITM.ItemCode = T1.ItemCode
INNER JOIN OINV ON OINV.DocEntry = T1.DocEntry
WHERE T1.CardCode = N'OT-05453' AND T1.ItemCode NOT IN (SELECT DISTINCT U_ItemCode FROM [#BP2] WHERE U_CardCode = N'OT-05453' )) t1
INNER JOIN
(SELECT
P.ItemCode,
[2017] [2017],
[2018] [2018],
[2019] [2019]
FROM
(SELECT
INV1.ItemCode,
OINV.CardCode as C,
INV1.Quantity Volume,
year(INV1.[DocDate]) as year
FROM INV1 INNER JOIN OINV ON INV1.docentry = OINV.docentry
WHERE INV1.[docDate] between year(2007) and GETDATE() AND OINV.cardcode = N'OT-05453'
) S
Pivot
(sum([volume]) For year IN ([2017],[2018],[2019])) P) t2
on t1.ItemCode = t2.ItemCode
EDIT: changed wrong alias in select clause

Dynamic Pivots for year in SQL Server

I'm trying to find a better way of reporting on some of our data within SQL Server, currently we have a report that looks at sales value in a certain country pivoted by year.
The report give me the correct data, but every year i'm having to add an extra column in for the new year. I've read a little bit about Dynamic pivot queries, but I cannot make them to work.
Here is my current query:
SELECT
isnull([TYPE],'Total') as 'Type',
sum(isnull([2010],0)) as '2010',
sum(isnull([2011],0)) as '2011',
sum(isnull([2012],0)) as '2012',
sum(isnull([2013],0)) as '2013',
sum(isnull([2014],0)) as '2014',
sum(isnull([2015],0)) as '2015',
sum(isnull([2016],0)) as '2016',
sum(isnull([2017],0)) as '2017',
sum(isnull([2018],0)) as '2018',
sum(isnull([2010],0) +isnull([2011],0) +isnull([2012],0) +isnull([2013],0) +isnull([2014],0) +isnull([2015],0) +isnull([2016],0) +isnull([2017],0) +isnull([2018],0)) as 'total'
FROM
(
SELECT
T3.Name 'Type' ,
DATEPART(YEAR,T0.DocDate) 'Year',
SUM(T1.totalsumsy) 'Quantity'
FROM
OINV T0 with (nolock) INNER JOIN
INV1 T1 with (nolock) ON T0.DocEntry = T1.DocEntry left join
INV12 t9 with (nolock) on t0.DocEntry = t9.DocEntry inner join
OCRD t7 with (nolock) on t0.CardCode = t7.CardCode INNER JOIN
[#AA_REGION] T8 ON case when isnull(t0.u_b2c,'n') = 'y' then t9.countrys else ISNULL(T7.U_COUNTRY,T7.COUNTRY) end = T8.CODE AND T8.code = 'au' INNER JOIN
OITM T2 with (nolock) ON T1.ItemCode = T2.ItemCode LEFT JOIN
[#AA_ITEMTYPES] T3 ON T2.U_CATEGORY = T3.Code LEFT JOIN
[#AA_STYLE] T4 ON T2.U_Style = T4.Code LEFT JOIN
[#AA_STYLEGROUP] T5 ON T4.U_GROUP = T5.Code LEFT JOIN
[#AA_ANIMAL] T6 ON T2.U_ANIMAL = T6.Code
WHERE
T5.Code = '010' AND
T6.CODE = '001' and
T0.DocDate >= '01.01.2010'
GROUP BY
T3.Name ,
DATEPART(YEAR,T0.DocDate)
)PS
PIVOT
(SUM(Quantity) for [Year] in ([2010],[2011],[2012],[2013],[2014],[2015],[2016], [2017], [2018]) ) as pvt
group by
[type] with rollup
order by sum(isnull([2010],0) +isnull([2011],0) +isnull([2012],0) +isnull([2013],0) +isnull([2014],0)+isnull([2015],0)+isnull([2016],0)) desc
Can anyone point me in the right direction to make the above query dynamic by year?

How to modify an SQL query with sub query to get an extra column

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:
SELECT (
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
This evaluates the subquery for each row, whereas if you re-wrote as so:
SELECT LastGRN.LastGRNDate
FROM OITM TO
LEFT JOIN
( SELECT PDN1.ItemCode, [LastGRNDate] = MAX(OPDN.DocDate)
FROM dbo.PDN1
INNER JOIN OPDN
ON PDN1.DocEntry = OPDN.DocEntry
GROUP BY PDN1.ItemCode
) LastGRN
ON LastGRN.ItemCode = T0.ItemCode
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:
SELECT [FirstOfThisMonth] = DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0),
[FirstOfLastMonth] = DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE() - 1), 0)
The same principle of joins rather than correlated subqueries can also be applied to your quantity columns, and this gives access to the WhsCode columns, it is not necessary, but I have used a common table expression to clean up the query (using the date logic from above)
WITH Quantities AS
( SELECT [DocMonth] = DATEADD(MONTH, DATEDIFF(MONTH, 0, IONV.DocDate),
Inv1.WhsCode,
ItemCode,
[Quantity] = SUM(Quantity)
FROM dbo.Inv1
INNER JOIN OINV
ON Inv1.DocEntry = OINV.DocEntry
GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, IONV.DocDate), WhsCode, itemCode
)
SELECT T0.ItemCode,
[Current Period] = COALESCE(Cur.Quantity, 0),
[Previous Period] = COALESCE(prev.Quantity, 0),
[60-90] = COALESCE(prev2.Quantity, 0)
FROM OITM T0
LEFT JOIN Quantities cur
ON cur.ItemCode = T0.ItemCode
AND cur.DocDate = DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0)
AND Cur.WhsCode = [%2]
LEFT JOIN Quantities prev
ON prev.ItemCode = T0.ItemCode
AND prev.DocDate = DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP) - 1, 0)
AND prev.WhsCode = [%2]
LEFT JOIN Quantities prev2
ON prev2.ItemCode = T0.ItemCode
AND prev2.DocDate = DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP) - 2, 0)
AND prev2.WhsCode = [%2]
Combining all this into your final query gives:
SELECT T0.CardCode,
T2.CardName,
T0.CodeBars,
T0.ItemCode,
T0.ItemName,
T3.Price,
T1.AvgPrice,
T1.OnHand,
T1.MinStock,
T1.MaxStock,
T0.NumInBuy AS Packsize,
T0.LstSalDate
[Current Period] = COALESCE(Cur.Quantity, 0),
[Previous Period] = COALESCE(prev.Quantity, 0),
[60-90] = COALESCE(prev2.Quantity, 0)
LastGRN.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
LEFT JOIN Quantities cur
ON cur.ItemCode = T0.ItemCode
AND cur.DocDate = DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0)
AND Cur.WhsCode = [%2]
LEFT JOIN Quantities prev
ON prev.ItemCode = T0.ItemCode
AND prev.DocDate = DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP) - 1, 0)
AND prev.WhsCode = [%2]
LEFT JOIN Quantities prev2
ON prev2.ItemCode = T0.ItemCode
AND prev2.DocDate = DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP) - 2, 0)
AND prev2.WhsCode = [%2]
LEFT JOIN
( SELECT PDN1.ItemCode, [LastGRNDate] = MAX(OPDN.DocDate)
FROM dbo.PDN1
INNER JOIN OPDN
ON PDN1.DocEntry = OPDN.DocEntry
GROUP BY PDN1.ItemCode
) LastGRN
ON LastGRN.ItemCode = T0.ItemCode
WHERE T3.PriceList = '3'
AND T4.WhsName = [%0]
AND T5.ItmsGrpNam = [%1]
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 APPLY to allow you to access multiple columns from it. e.g.
SELECT T0.Code, cur.WhsCode, cur.Expr1 AS [Current Period]
FROM OITM T0
OUTER APPLY
( SELECT INV1.WhsCode, 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())
) cur
All your subqueries contain in the where clause the following: INV1.WhsCode = [%2]
That means instead of INV1.WhsCode you can just return [%2] like this:
SELECT [%2] as WhsCode,
T0.CardCode,
T2.CardName,
T0.CodeBars,
......
This assumes that [%2] and the other similar tokens get replaced by the app with something SQL Server understands, before this gets send to get executed.