trying to add a selection to the following query - sql

I nee to add a user selected date (DocDate) to the following query
SELECT DocNum, CardCode, CardName FROM ORDR WHERE DOCENTRY NOT IN(
select DISTINCT(T0.DOCENTRY)
from ORDR T0 JOIN RDR1 T1 ON T0.DOCENTRY = T1.DOCENTRY
LEFT JOIN OITM T2 ON T1.ITEMCODE = T2.ITEMCODE
LEFT JOIN OITB T3 ON T2.ItmsGrpCod = T3.ItmsGrpCod
WHERE T3.ItmsGrpNam = 'Carriage Out'
AND T0.DocType = 'I'
)
AND DOCTYPE = 'I'

Improved query - not yet an answer though.
SELECT DocNum, CardCode, CardName
FROM ORDR
WHERE DOCENTRY NOT IN
(
select T0.DOCENTRY
from ORDR T0
JOIN RDR1 T1 ON T0.DOCENTRY = T1.DOCENTRY
LEFT JOIN OITM T2 ON T1.ITEMCODE = T2.ITEMCODE
LEFT JOIN OITB T3 ON T2.ItmsGrpCod = T3.ItmsGrpCod
AND T3.ItmsGrpNam = 'Carriage Out'
WHERE T0.DocType = 'I'
)
AND DOCTYPE = 'I'

where YEAR(t0.DocDate) = YEAR(#date) where #date is your sent input, you can either check for specific date, same year or month.

Related

How to link Purchase Order and AP Invoice?

I'm trying to write a query that returns AP Invoice number(s) by keying a Purchase Order number in SAP B1.
PO --> Goods Receipt --> AP Invoice
SELECT DISTINCT
T0.DocNum AS PO,
T4.DocNum AS 'AP Inv'
FROM OPOR T0
LEFT OUTER JOIN PDN1 T1 ON T0.DocEntry = T1.BaseEntry
LEFT OUTER JOIN OPDN T2 ON T1.DocEntry = T2.DocEntry
LEFT OUTER JOIN PCH1 T3 ON T2.DocEntry = T3.BaseEntry
AND T1.LineNum = T3.BaseLine
AND T1.ItemCode = T3.ItemCode
LEFT OUTER JOIN OPCH T4 ON T3.DocEntry = T4.DocEntry
WHERE T0.DocNum = '[%0]'
PO --> Reserved AP Invoice --> Goods Receipt
SELECT DISTINCT
T2.DocNum AS PO,
T0.DocNum AS 'AP Inv'
FROM OPCH T0
INNER JOIN PCH1 T1 ON T0.DocEntry = T1.DocEntry
INNER JOIN OPOR T2 ON T2.DocEntry = T1.BaseEntry
WHERE T1.BaseType = '22'
AND T2.DocNum = '[%0]'
Is there a way to get AP Invoice number(s) in a query?

How do I get this Right outer join to work?

I'm attempting to show all sales orders and, if they have them, the delivery note. I've got a query showing all orders but no matter how I join it to the next table, I continue to get results for only orders with delivery notes. I want NULL to be present for delivery notes if there are none on record.
I've tried left, right, and inner joins and they're all returning the same number of results which baffles me. I thought I had an understanding of joins before today.
This part shows how many sales orders exist. I want all results from this to appear in the next query
select t0.docnum SalesOrder, t1.itemcode, t1.linenum rdr1line
from ordr t0 inner join rdr1 t1 on t1.docentry = t0.docentry
where t0.CANCELED = 'N';
This part shows how many sales orders exist with a Delivery Note, but is not including orders that don't have delivery notes.
select t0.docnum SalesOrder, t1.itemcode, t2.docnum DelivNoteNum, t3.baseline inv1base, t1.linenum rdr1line, t3.linenum dln1line
from ordr t0 inner join rdr1 t1 on t1.docentry = t0.docentry
right outer join odln t2 on t2.docentry = t1.trgetentry
right outer join dln1 t3 on t3.docentry = t2.docentry and t3.baseline = t1.linenum and t3.ItemCode = t1.ItemCode
where t0.CANCELED = 'N' and t2.canceled = 'N';
Expected results should be the same number of rows in each table. Actual results are only ordered with delivery notes.
Use left join, not right join. If you want all orders then start with that table. Filters on subsequent tables should go into the on clause:
select t0.docnum SalesOrder, t1.itemcode, t2.docnum DelivNoteNum,
t3.baseline inv1base, t1.linenum rdr1line, t3.linenum dln1line
from ordr t0 left join
rdr1 t1
on t1.docentry = t0.docentry left join
odln t2
on t2.docentry = t1.trgetentry and t2.canceled = 'N' left join
dln1 t3
on t3.docentry = t2.docentry and
t3.baseline = t1.linenum and
t3.ItemCode = t1.ItemCode
where t0.CANCELED = 'N';

Cumulative total based off of two columns

So I am looking to get an extra column into my query that calculates a cumulative balance based off of the credit/debit columns.
My query looks like this so far:
SELECT T1.[RefDate], T1.[TransId], T1.[BaseRef], T1.[LineMemo], T3.[Dscription], T1.[Debit], T1.[Credit], T4.[AcctName]
FROM OJDT T0
right JOIN JDT1 T1 ON T0.TransId = T1.TransId
left JOIN OPCH T2 ON T0.TransId = T2.TransId
left JOIN PCH1 T3 ON T3.DocEntry = T2.DocEntry
left JOIN OACT T4 ON T1.Account = T4.AcctCode
WHERE T4.[AcctCode] = [%0] AND
T1.[RefDate] BETWEEN [%1] AND [%2]
You could use windowed SUM:
SELECT T1.[RefDate], T1.[TransId], T1.[BaseRef], T1.[LineMemo], T3.[Dscription],
T1.[Debit], T1.[Credit], T4.[AcctName],
SUM(ISNULL(Debit,0)+ISNULL(Credit,0)) OVER(PARTITION BY ... ORDER BY refDate)
FROM OJDT T0
right JOIN JDT1 T1 ON T0.TransId = T1.TransId
left JOIN OPCH T2 ON T0.TransId = T2.TransId
left JOIN PCH1 T3 ON T3.DocEntry = T2.DocEntry
left JOIN OACT T4 ON T1.Account = T4.AcctCode
WHERE T4.[AcctCode] = [%0] AND
T1.[RefDate] BETWEEN [%1] AND [%2];
If Debit column contains positive values you need to prefix it with -.
Documentation around OVER: https://msdn.microsoft.com/en-us/library/ms189461(v=SQL.110).aspx
You'll probably find example C to be the most useful though it looks like you don't want to PARTITION, you want to use RANGE.
you'll want something like this for your calculated column:
SUM(ISNULL(Debit,0)+ISNULL(Credit,0))
OVER(RANGE UNBOUNDED PRECEDING AND CURRENT ROW) AS RunningTotal
This will result in a query something like:
SELECT T1.[RefDate], T1.[TransId], T1.[BaseRef], T1.[LineMemo], T3.[Dscription], T1.[Debit], T1.[Credit], T4.[AcctName],
SUM(ISNULL(Debit,0)+ISNULL(Credit,0))
OVER(RANGE UNBOUNDED PRECEDING AND CURRENT ROW) AS RunningTotal
FROM OJDT T0
right JOIN JDT1 T1 ON T0.TransId = T1.TransId
left JOIN OPCH T2 ON T0.TransId = T2.TransId
left JOIN PCH1 T3 ON T3.DocEntry = T2.DocEntry
left JOIN OACT T4 ON T1.Account = T4.AcctCode
WHERE T4.[AcctCode] = [%0] AND
T1.[RefDate] BETWEEN [%1] AND [%2]

List of items with last Shipment Date

I'm trying to get a list of items in stock for an order, with the latest confirmed leadtime given by our supplier. If I try to use the Query like this it will return every leadtime ever confirmed for that item. How do I get it to only show me the last one?
SELECT
T0.DocNum AS Order,
T1.ItemCode AS Item,
T2.U_Internal_Code AS IntItem,
CAST (((T2.onhand+T2.OnOrder)-T2.IsCommited) as int) AS Stock,
T3.ShipDate
FROM
ORDR T0
INNER JOIN RDR1 T1 ON T0.DocEntry = T1.DocEntry
INNER JOIN OITM T2 ON T1.ItemCode = T2.ItemCode
INNER JOIN POR1 T3 ON T2.U_Bestelcode = T3.U_Bestelcode
WHERE T0.DocNum='1234' AND T3.ShipDate=(SELECT MAX (ShipDate) FROM POR1 WHERE T3.ShipDate = ShipDate)
ORDER BY T1.ItemCode
By filtering on WHERE T3.ShipDate = ShipDate you're going to get a different date for each row in T3.
I think you want something like WHERE T3.Vendor= Vendor to find the latest date for the vendor in total
Obviously dependent on your DB structure.
Change this
WHERE T0.DocNum='1234' AND T3.ShipDate=(SELECT MAX (ShipDate) FROM POR1 WHERE T3.ShipDate = ShipDate)
ORDER BY T1.ItemCode
to this
WHERE T0.DocNum='1234'
ORDER BY T3.ShipDate DESC, T1.ItemCode
limit 1
Try this one. Top 1 selects only one row which is at top. İf you write TOP 2 you can get 2 data from top.
For SQL
SELECT TOP 1
T0.DocNum AS Order,
T1.ItemCode AS Item,
T2.U_Internal_Code AS IntItem,
CAST (((T2.onhand+T2.OnOrder)-T2.IsCommited) as int) AS Stock,
T3.ShipDate
FROM
ORDR T0
INNER JOIN RDR1 T1 ON T0.DocEntry = T1.DocEntry
INNER JOIN OITM T2 ON T1.ItemCode = T2.ItemCode
INNER JOIN POR1 T3 ON T2.U_Bestelcode = T3.U_Bestelcode
WHERE T0.DocNum='1234' AND T3.ShipDate=(SELECT MAX (ShipDate) FROM POR1 WHERE T3.ShipDate = ShipDate)
ORDER BY T1.ItemCode DESC;
For MySQL
SELECT
T0.DocNum AS Order,
T1.ItemCode AS Item,
T2.U_Internal_Code AS IntItem,
CAST (((T2.onhand+T2.OnOrder)-T2.IsCommited) as int) AS Stock,
T3.ShipDate
FROM
ORDR T0
INNER JOIN RDR1 T1 ON T0.DocEntry = T1.DocEntry
INNER JOIN OITM T2 ON T1.ItemCode = T2.ItemCode
INNER JOIN POR1 T3 ON T2.U_Bestelcode = T3.U_Bestelcode
WHERE T0.DocNum='1234' AND T3.ShipDate=(SELECT MAX (ShipDate) FROM POR1 WHERE T3.ShipDate = ShipDate)
ORDER BY T1.ItemCode DESC
LIMIT 1;

How to implement a multiple criteria in Where clause?

I am wanting to see ONLY the documents where 3 criteria's are met but the 3 criteria's have multiple criteria's.
Here is my code:
SELECT
t0.DocNum
FROM
dbo.OIPF t0 inner join IPF2 t1 ON t0.DocEntry = t1.DocEntry
inner join IPF1 t2 on t0.DocEntry = t2.DocEntry
WHERE
(t1.OhType = 'W' and t1.CostSum > 0) and
(t1.OhType = 'F' and T1.CostSum > 0) and
(t1.OhType = 'Q' and T1.CostSum > 0)
This gives me zero results. But to me that is how I would make sure that all 3 of these cost types have totals greater than 0.
Could any one help me on this?
Thanks!!
You have 3 different criteria. Try or but not and.
SELECT
t0.DocNum
FROM
dbo.OIPF t0 inner join IPF2 t1 ON t0.DocEntry = t1.DocEntry
inner join IPF1 t2 on t0.DocEntry = t2.DocEntry
WHERE
(t1.OhType = 'W' and t1.CostSum > 0) or
(t1.OhType = 'F' and T1.CostSum > 0) or
(t1.OhType = 'Q' and T1.CostSum > 0);
If I understand your question correctly, Alex_Bender's answer would be correct.
Another simpler way to express it which may be simpler to understand would be like this:
SELECT
t0.DocNum
FROM
dbo.OIPF t0 inner join IPF2 t1 ON t0.DocEntry = t1.DocEntry
inner join IPF1 t2 on t0.DocEntry = t2.DocEntry
WHERE t1.OhType IN ('W', 'F', 'Q')
AND t1.CostSum > 0
SELECT
t0.DocNum
FROM dbo.OIPF t0
inner join IPF2 t1 ON t0.DocEntry = t1.DocEntry
--inner join IPF1 t2 ON t0.DocEntry = t2.DocEntry
WHERE t1.OhType in ('W' , 'F', 'Q') and t1.CostSum > 0
What you are trying to do is equivalent to this. Also, i am not sure why the table IPF1 is being joined on, if it is not being used.