What is the link in SAP Business One between Sales Orders, Deliveries, and Invoices - hana

I'm trying to join ORDR, ODLN and OINV in a SAP Business One query, but I can't seem to find a field that they share in common.
There must be some record somewhere that links one to another.
Are they linked via a separate table? Or am I missing something obvious?
I am using SAP HANA as my DB, so queries in HANA are preferred rather than MSSQL.

First, credit to Eralper for their answer, as the link contained in it helped me find the solution I was looking for. However, their solution does not include an explanation and does not quite give the result that is being looked for.
The main information for a Sales Order in SAP is stored in two tables, ORDR and RDR1. ORDR has one line for each Sales Order, while RDR1 has one line for each product row on the Sales Order.
Delivery Notes and Invoices (and basically any document in SAP) follow this pattern.
Why is this important to this question? Because the column that contains the data to link Sales Orders, Delivery Notes and Invoices is in RDR1 (or the similar variant). It's name is TrgetEntry.
As there is a row for each product on a Sales Order, we can't simply do a join, as any Sales Order that has more than one product will appear multiple times in the result. The following query uses grouping to show a table that has a line for each Sales Order, and has the needed information to link it to Delivery Notes.
SELECT T0."DocEntry" AS "SO DE", T0."DocNum" AS "Sales Order Number", T1."TrgetEntry" AS "SO TE", COUNT(T0."DocNum") AS "Rows"
FROM ORDR T0
LEFT JOIN RDR1 T1 ON T0."DocEntry" = T1."DocEntry"
GROUP BY T0."DocEntry", T0."DocNum", T1."TrgetEntry"
By just changing the table names, similar queries can be created for Delivery Notes and Invoices.
Then you can use the TrgetEntry and DocEntry to link the various results.
The final code I use to show Sales Orders, their related Deliveries and Invoices is the following:
SELECT S0."SalesOrderNumber", S1."DeliveryNumber", S2."DocNum" AS "InvoiceNumber", S0."Rows", S2."DocTotal"
FROM (SELECT T0."DocEntry" AS "SO_DE", T0."DocNum" AS "SalesOrderNumber", T1."TrgetEntry" AS "SO_TE", COUNT(T0."DocNum") AS "Rows"
FROM ORDR T0
LEFT JOIN RDR1 T1 ON T0."DocEntry" = T1."DocEntry"
GROUP BY T0."DocEntry", T0."DocNum", T1."TrgetEntry") S0
LEFT JOIN (SELECT T0."DocEntry" AS "DN_DE", T0."DocNum" AS "DeliveryNumber", T1."TrgetEntry" AS "DN_TE"
FROM ODLN T0
LEFT JOIN DLN1 T1 ON T0."DocEntry" = T1."DocEntry"
GROUP BY T0."DocEntry", T0."DocNum", T1."TrgetEntry") S1 ON S0."SO_TE" = S1."DN_DE"
LEFT JOIN OINV S2 ON S1."DN_TE" = S2."DocEntry"

Please check https://archive.sap.com/discussions/thread/1440163
There following relationship is given
SELECT Distinct(T0.DocNum ),T0.DocDate, T0.CardCode, T0.CardName, T1.ItemCode, T1.Quantity, T1.Price,T1.TotalSumSy, T0.DocTotal
FROM ORDR T0
INNER JOIN RDR1 T1 ON T0.DocEntry = T1.DocEntry
INNER JOIN ODLN T2 ON T2.DocEntry = T1.TrgetEntry
INNER JOIN DLN1 T3 on T3.DocEntry = T2.Docentry
INNER JOIN OINV T4 ON T4.DocEntry = T3.TrgetEntry
INNER JOIN INV1 T5 ON T5.DocEntry = T4.DocEntry
LEFT JOIN ORDN T6 ON T6.DocEntry = T5.TrgetEntry
LEFT JOIN RDN1 T7 ON T7.DocEntry = T6.DocEntry
So following relation is also true
SELECT *
FROM ODLN T2
INNER JOIN DLN1 T3 on T3.DocEntry = T2.Docentry
INNER JOIN OINV T4 ON T4.DocEntry = T3.TrgetEntry

Related

Optimising SQL Query with multiple joins, reducing query speed

I'd like some advice on how to optimize the code below. I have attached the relationship of table above, any feedback or direction you could point me to will be appreciated.
The current query seems to be taking quite long to process.
SELECT CUSTINVOICETRANS.INVENTTRANSID, CUSTINVOICETRANS.INVOICEDATE, CUSTINVOICETRANS.INVOICEID, CUSTINVOICETRANS.ITEMID, CUSTINVOICETRANS.LINEAMOUNT, CUSTINVOICETRANS.LINEAMOUNTTAX, CUSTINVOICETRANS.ORIGSALESID, CUSTINVOICETRANS.QTY, CUSTINVOICETRANS.SUMLINEDISC, CUSTINVOICEJOUR.CUSTGROUP, CUSTINVOICEJOUR.INVOICEACCOUNT, CUSTINVOICEJOUR.SALESID, SALESTABLE.VCORDERMODE, SALESTABLE.VCORDERRT, VCSALESTABLEINFO.RCVDATE, VCSALESTABLEINFO.SHPCSTMCD, VCSALESTABLEINFO.VCORIGINALINVOICEDATE, SALESLINE.DATAAREADID, SALESLINE.INVENTTRANSID, VCSALESLINEINFO.RLLINEID
FROM CUSTINVOICETRANS
INNER JOIN CUSTINVOICEJOUR
ON CUSTINVOICETRANS.INVOICEID = CUSTINVOICEJOUR.INVOICEID
AND CUSTINVOICETRANS.INVOICEDATE = CUSTINVOICEJOUR.INVOICEDATE
AND CUSTINVOICETRANS.INVOICEDATE>=DATEADD(DAY,-7,GETDATE())
INNER JOIN SALESTABLE
ON CUSTINVOICETRANS.ORIGSALESID = SALESTABLE.SALESID
AND CUSTINVOICETRANS.INVOICEDATE>=DATEADD(DAY,-7,GETDATE())
INNER JOIN VCSALESTABLEINFO
ON CUSTINVOICETRANS.ORIGSALESID = VCSALESTABLEINFO.SALESID
AND CUSTINVOICETRANS.INVOICEDATE>=DATEADD(DAY,-7,GETDATE())
INNER JOIN SALESLINE
ON CUSTINVOICETRANS.ORIGSALESID = SALESLINE.SALESID
AND CUSTINVOICETRANS.INVOICEDATE>=DATEADD(DAY,-7,GETDATE())
INNER JOIN VCSALESLINEINFO
ON SALESLINE.INVENTTRANSID = VCSALESLINEINFO.INVENTTRANSID```
You can use cte to filter first your customer invoice transactions before joining other tables.
WITH cte as
(
SELECT INVENTTRANSID, INVOICEDATE, INVOICEID
, ITEMID, LINEAMOUNT, LINEAMOUNTTAX
, ORIGSALESID, QTY, SUMLINEDISC
FROM CUSTINVOICETRANS WHERE INVOICEDATE>=DATEADD(DAY,-7,GETDATE())
)
SELECT t1.*, t2.CUSTGROUP, t2.INVOICEACCOUNT, t2.SALESID
, t3.VCORDERMODE, t3.VCORDERRT
, t4.RCVDATE, t4.SHPCSTMCD, t4.VCORIGINALINVOICEDATE
, t5.DATAAREADID, t5.INVENTTRANSID
, t6.RLLINEID
FROM cte t1
INNER JOIN CUSTINVOICEJOUR t2 on t2.INVOICEID = t1.INVOICEID and t1.INVOICEDATE = t2.INVOICEDATE
INNER JOIN SALESTABLE t3 on t3.SALESID = t1.ORIGSALESID
INNER JOIN VCSALESTABLEINFO t4 on t4.SALESID = t1.ORIGSALESID
INNER JOIN SALESLINE t5 on t5.SALESID = t1.ORIGSALESID
INNER JOIN VCSALESLINEINFO t6 on t6.INVENTTRANSID = t5.INVENTTRANSID
Pull the first INNER JOIN outcome to a dataframe / temp table t1.
Join the same with second INNER Join dataset.
pull the data into another temp table / data frame.
Drop the temp table t1 at the end.
Follow the step for for subsequesnt joins.
Regards

How to Join tables in SQL with SUM Function and Group?

I'm creating a report to display project wise cost and revenue. I need to group sum of A/P invoices and Sum of A/R invoices according to the project.
Same project could have many A/P invoices and A/R invoices which can include same Items.If there have 5 A/P invoices with same Items Like A,B,C I need to take Item wise sum of the amount also(Line wise Total sum)
All projects names and code(PrjCode-Primary Key) based in a separate table of OPRJ
Other Tables Structure as follows
A/P Invoice - OPCH(Main details) Link with PCH1(Item Details)
On Primary Key - DocEntry
PCH1 Lines Link with OPRJ on PCH1.Project = OPRJ.PrjCode
A/R Invoice - OINV(Main details) Link with INV1(Item Details)
On Primary Key - DocEntry
INV1 Lines Link with OPRJ on INV1.Project = OPRJ.PrjCode
I tries this query but couldn't get sum
select a.PrjCode,a.PrjName,b.ItemCode,sum(b.LineTotal),Sum(c.DocTotal),sum(e.DocTotal)
from OPRJ a
Left Join PCH1 b on b.Project = a.PrjCode
Left Join OPCH c on c.DocEntry = b.DocEntry
Left Join INV1 d on d.Project = a.PrjCode and b.Project = d.Project
Left Join OINV e on e.DocEntry = d.DocEntry
Group by
a.PrjCode,a.PrjName,c.DocTotal,e.DocTotal,b.ItemCode,b.LineTotal
Output what I expect is as follows
Sql Output without sum
you should remove the values you're summing up from the group by:
select a.PrjCode,a.PrjName,b.ItemCode,sum(b.LineTotal),Sum(c.DocTotal),sum(e.DocTotal)
from OPRJ a
Left Join PCH1 b on b.Project = a.PrjCode
Left Join OPCH c on c.DocEntry = b.DocEntry
Left Join INV1 d on d.Project = a.PrjCode and b.Project = d.Project
Left Join OINV e on e.DocEntry = d.DocEntry
Group by
a.PrjCode,a.PrjName,b.ItemCode

items are repeated in SAP B1 query

Below query is giving me correct output on quantity (but have to add quantities of repeated styles) but item code and item description is repeated. i want to see one time code having Total PO qty and what in stock.
Can you please advise what's wrong with this query.
Thanks
Shahzad Ahmed enter image description here
SELECT
T1.[ItemCode],
T1.[Dscription],
sum(T1.[Quantity]) as 'PO QTY',
T3.[OnHand]
FROM
ORDR T0 INNER JOIN RDR1 T1 ON T0.[DocEntry] = T1.[DocEntry]
INNER JOIN OITM T2 ON T1.[ItemCode] = T2.[ItemCode]
INNER JOIN OITW T3 ON T2.[ItemCode] = T3.[ItemCode]
WHERE
T0.[CardCode] = 'c00192' and
T0.[NumAtCard] Like '818276%%' and
T3.[WhsCode] = '161'
GROUP BY T1.[ItemCode], T1.[Dscription], T1.[Quantity], T3.[OnHand]
You just need to remove T1.[Quantity] from your GROUP BY. You should read on how to use a Group by, but to summarize, when you're calling a group by, you're asking to look for rows with the same values in some columns.
For exemple, here you want to add the quantities of every row with the same ItemCode, Dscription, OnHand, but you're asking to also look for rows with the same Quantity here.
Here is a good article on GROUP BY

SAP B1 Link AP invoice to PO user

I am trying to generate a query that will return header information for Payment-Hold AP Invoices but also show the username that entered the originating Purchase Order.
Some of my invoices do not have a relationship history so I wouldn't expect any user details to be returned but still need the invoice header information. Others have multiple GRPO entries and are therefore returning 2-3 lines where I only need one. Below is my query.
thanks in advance.
select distinct T0."DocNum"
,T0."DocDate"
,T0."DocType"
,T0."CardCode"
,T0."CardName"
,T0."DocStatus"
,T0."GroupNum"
,T0."DocDueDate"
,T0."DocCur"
,T0."DocTotal"
,T0."DocTotalFC"
,T0."PayBlock"
,T0."PaymentRef"
--,T1."DocEntry"
--,T2."DocEntry"
--,T4."DocNum"
--,T3."ItemCode"
--,IFNULL(T4."UserSign", 0) AS "User_Code"
-- ,T4."UserSign"
,T5."U_NAME" as "Purc_User"
,IFNULL(T5."U_NAME",'') as "PURC_USER"
,'HT' as Entity
,T0."Comments"
FROM OPCH T0
left JOIN PCH1 T1 ON T1."DocEntry" = T0."DocEntry"
left JOIN PDN1 T2 on T1."BaseEntry"= T2."DocEntry" and T1."BaseLine"= T2."LineNum"
left JOIN POR1 T3 on T2."BaseEntry" = T3."DocEntry" and T2."BaseLine" = T3."LineNum"
left JOIN OPOR T4 on T4. "DocEntry" = T3."DocEntry"
left JOIN OUSR T5 on T5."USERID" = T4."UserSign"
where T0."DocStatus" = 'O'
and T0."PayBlock" = 'Y'
order by T0."DocNum"

SBO tables Relationship (AR INVOICE-INCOMING Payment)

am making a query that bring Incoming Payments details , that include payment means , details of payment means , and then some UDFS from the related A/R invoice(s) , in addition to some UDF from an object that relate to a UDF in the AR INVOICE ,
now every time am running my query it show no result.
Am sure there is something I missing here or incorrect but so far couldn't find it .
if any one can help me with this i will be thankful
here is the query :
SELECT T1.[baseAbs] AS INVOICENO, T0.[DocDate],t0.[trsfrdate],t0.[trsfrref], T0.[CardName],T0.[Doctotal],T4.[VoucherNum] ,
T0.[Comments], T1.[DocNum] AS PAYMENTNO, T2.[Phone1],
T0.[CashSum], T0.[CreditSum], T0.[CheckSum], T0.[TrsfrSum],
T3.[DueDate] AS CHECKDATE, T3.[CheckNum] AS CHECKNO, T3.[Details] AS MAYBEBANKNAME
, t5.[U_UnitCode],t5.[U_Type],t7.[WhsName],t7.[city] ,
t8.U_FloorNo
FROM ORCT T0
inner JOIN RCT2 T1 ON T0.[DocEntry] = T1.[DocNum]
inner JOIN OINV T5 ON T5.[docnum] =T1.[BaseAbs]
INNER JOIN RCT1 T3 ON T0.[DocNum] = T3.[DocNum]
INNER JOIN RCT3 T4 ON T0.[DocNum] = T4.[DocNum]
INNER JOIN OCRD T2 ON T0.[CardCode] = T2.[CardCode]
INNER JOIN INV1 T6 ON T5.[DocEntry] = T6.[DocEntry]
INNER JOIN OWHS T7 ON T6.[WhsCode] = T7.[WhsCode]
INNER JOIN [dbo].[#AUND] T8 ON T5.[U_UnitCode] = T8.[Code]
the query is now working fine now , the problem was in inner join , it should been replaced to left join ,
here is the fixed one :
select T0.DocNum as 'Payment Number',T0.DocDate 'Payment Date',T0.CardCode,
T0.CardName 'Customer Name',T1.BankCode 'Bankcode',T3.BankName 'Bank Name', T2.Phone1 ,
T0.CreditSum,
T0.CashSum,
T0.TrsfrSum,
t0.CheckSum,
t1.CheckNum as 'Check Number',
t1.DueDate as 'check date',
t6.VoucherNum as 'Voucher Number',
t0.TrsfrRef as 'Transfer No',
t0.TrsfrDate AS 'Transfer Date',
ousr.USER_code as 'user code',
T5.DocNum, t11.U_P_BuildingName as 'Building Name',
CASE when T5.DocNum is null then 'On Account' else 'Paid For Invoice' END AS 'Payment Status',
CASE when T5.DocStatus = 'O' then 'Open' else 'Closed' END AS ' Invoice Status',
T4.SumApplied as 'Amount Paid on Invoice',T9.U_FloorNo,T5.U_UnitCode,T5.U_Type,
t0.DocTotal as 'Payment Total',t5.DocTotal as'Invoice Total' , t8.City,
t0.Comments as'Remarks'
from ORCT T0
left join rct1 T1 on T0.DocNum=T1.DocNum
left join ocrd T2 on T2.CardCode=T0.CardCode
left outer join ODSC T3 on T3.BankCode=T0.BankCode
left join RCT2 T4 on T0.DocNum = T4.DocNum
left join RCT3 T6 on T0.DocNum = T6.DocNum
left join OINV T5 on T4.DocEntry = T5.DocEntry and T5.ObjType = T4.InvType
left join oitm t11 on t5.u_unitcode = t11.ItemCode
LEFT JOIN OWHS T8 ON T11.U_P_BuildingNum = T8.WhsCode
LEFT JOIN [dbo].[#AUND] T9 ON T5.[U_UnitCode] = T9.[Code]
INNER JOIN OSLP T10 ON T5.[SlpCode] = T10.[SlpCode]
inner join ousr on ousr.USERID = t0.usersign
where
T4.InvType <> '14' and T0.[Canceled] = 'N' and t0.docnum=200001
I think there's a few issues with your query, starting with the join from ORCT to RCT2.
I've created similar queries in the past, here's one which I know works, maybe you can use it to adjust yours. For one thing, you'll definitely need to adjust a lot of those inner joins to outer joins, as a lot of the relations between Payments and it's parent business objects (like Invoices) are very loose and may not always apply.
Note that the query below is looking specifically for Invoices in the RCT2 table (this is the "lines" section of the Incoming Payment object), hence the J002.InvType = 13 condition.
SELECT *
FROM [ORCT] J001
LEFT OUTER JOIN [RCT2] J002 ON J002.DocNum = J001.DocNum AND J002.InvType = 13
LEFT OUTER JOIN [OINV] J003 ON J003.DocEntry = J002.DocEntry
LEFT OUTER JOIN [OACT] J004 ON J004.AcctCode = J001.CashAcct
LEFT OUTER JOIN [RCT1] J005 ON J005.DocNum = J001.DocNum