Only include emails once in SQL query - sql

Having a bit of a dead brain moment right now.
I have this query to give me BP Codes,Names, Contacts and Sales Person. I only want to include an existing email once in the query. If the same email exists for multiple BP's then only 1 BP should be included (lets say TOP 1).
SELECT DISTINCT
OCRD.CardCode,
OCRD.CardName,
OCPR.Name,
OCPR.E_MailL,
OSLP.SlpName
FROM OCRD
INNER JOIN OCRG ON OCRG.GroupCode = OCRD.GroupCode
INNER JOIN OCPR ON OCPR.CardCode = OCRD.CardCode
INNER JOIN OOND ON OOND.IndCode = OCRD.IndustryC
INNER JOIN OSLP ON OCRD.SlpCode = OSLP.SlpCode
WHERE OCRG.GroupName <> 'Retail' AND
OOND.IndName = 'Aged Care' and
OCRD.frozenFor = 'N' AND
OCPR.E_MailL LIKE '%#%'
ORDER BY OCRD.CardCode ASC
For the life of me I cant figure it out right now. Any help will be appreciated.

Based on this stackoverflow post, I assume this might work
SELECT DISTINCT ON (OCPR.E_MailL)
OCRD.CardCode,
OCRD.CardName,
OCPR.Name,
OCPR.E_MailL,
OSLP.SlpName
FROM OCRD
INNER JOIN OCRG ON OCRG.GroupCode = OCRD.GroupCode
INNER JOIN OCPR ON OCPR.CardCode = OCRD.CardCode
INNER JOIN OOND ON OOND.IndCode = OCRD.IndustryC
INNER JOIN OSLP ON OCRD.SlpCode = OSLP.SlpCode
WHERE OCRG.GroupName <> 'Retail' AND
OOND.IndName = 'Aged Care' and
OCRD.frozenFor = 'N' AND
OCPR.E_MailL LIKE '%#%'
ORDER BY OCRD.CardCode ASC, OCRD.E_MAIL

Related

INNER JOIN from another INNER JOIN

I have a database with 3 tables :
PM_FLX_ENTE
PM_ST
PM_ANO_SP
and I would like to get PM_ANO_SP.L_ANO_SP for certain values of PM_ANO_L.L_ANO which contains a code number with '/'.
SELECT COUNT(RF_INTRN),TRIM(pm_st.c_st),TRIM(pm_ano_l.L_ANO)
FROM PM_FLX_ENTE
INNER JOIN PM_ST ON PM_FLX_ENTE.C_ST = PM_ST.C_ST
INNER JOIN PM_ANO_L ON PM_FLX_ENTE.C_ANO = pm_ano_l.c_ano
WHERE pm_flx_ente.C_ANO <> '0000'
AND pm_ano_l.c_lang = 'FR'
group by TRIM(pm_st.c_st), TRIM(pm_ano_l.L_ANO)
ORDER BY COUNT(RF_INTRN) DESC
Can you help me please
Are you seeing an error of some sort?
Please note, that when you do multiple inner joins, the previous join conditions have to be true for the other joins to work.
I.E
INNER JOIN PM_ST ON PM_FLX_ENTE.C_ST = PM_ST.C_ST
Has to evaluate true in order for the below to work
INNER JOIN PM_ANO_L ON PM_FLX_ENTE.C_ANO = pm_ano_l.c_ano
To solve this, you may want to change your INNER JOINs to LEFT JOINs
SELECT TRIM(pm_st.c_st),TRIM(pm_ano_l.L_ANO),COUNT(RF_INTRN)
FROM PM_FLX_ENTE
LEFT JOIN PM_ST ON PM_FLX_ENTE.C_ST = PM_ST.C_ST
LEFT JOIN PM_ANO_L ON PM_FLX_ENTE.C_ANO = pm_ano_l.c_ano
LEFT JOIN PM_ANO_SP ON PM_ANO_L.L_ANO = pm_ano_sp.l_ano_sp
WHERE pm_flx_ente.C_ANO <> '0000'
AND C_LANG = 'FR'
and pm_ano_l.L_ANO like '%/%'
GROUP BY pm_st.c_st,pm_ano_l.L_ANO

SQL: Summing across CASE statements returning wrong result

It's been ages since I've written complex SQL statements. I'm working in WordPress/WooCommerce and trying to sum orders against each customer.
When I started testing with this SQL statement, to just get a list of orders with customer info included, it works:
SELECT wp_users.ID as userID,
wp_posts.post_date,
wp_posts.post_type,
wp_users.user_email,
MAX(CASE WHEN wp_usermeta.meta_key = 'billing_first_name' THEN wp_usermeta.meta_value END) as firstName,
MAX(CASE WHEN wp_usermeta.meta_key = 'billing_last_name' THEN wp_usermeta.meta_value END) as lastName,
MAX(CASE WHEN wp_woocommerce_order_itemmeta.meta_key = '_line_total' THEN wp_woocommerce_order_itemmeta.meta_value END) as orderTotal
FROM wp_posts
INNER JOIN wp_postmeta
ON wp_postmeta.post_id = wp_posts.ID
INNER JOIN wp_users
ON wp_postmeta.meta_key = '_customer_user'
AND wp_users.ID = wp_postmeta.meta_value
INNER JOIN wp_usermeta
ON wp_usermeta.user_id = wp_users.ID
INNER JOIN wp_woocommerce_order_items
ON wp_woocommerce_order_items.order_id = wp_posts.ID
INNER JOIN wp_woocommerce_order_itemmeta
ON wp_woocommerce_order_itemmeta.order_item_id = wp_woocommerce_order_items.order_item_id
WHERE wp_posts.post_type IN ('shop_order','shop_subscription')
GROUP BY wp_posts.ID
Result is shown in the first image here: https://imgur.com/a/mZs9Iej
And if I sum those results in excel (there is only 1 test user so far), it shows $4281 as the total for that user.
If I then try and SUM in the SQL statement per user, like here (only two lines are changed, last MAX changed to SUM, and GROUP BY changed to wp_users.ID):
SELECT wp_users.ID as userID,
wp_posts.post_date,
wp_posts.post_type,
wp_users.user_email,
MAX(CASE WHEN wp_usermeta.meta_key = 'billing_first_name' THEN wp_usermeta.meta_value END) as firstName,
MAX(CASE WHEN wp_usermeta.meta_key = 'billing_last_name' THEN wp_usermeta.meta_value END) as lastName,
SUM(CASE WHEN wp_woocommerce_order_itemmeta.meta_key = '_line_total' THEN wp_woocommerce_order_itemmeta.meta_value END) as userTotal
FROM wp_posts
INNER JOIN wp_postmeta
ON wp_postmeta.post_id = wp_posts.ID
INNER JOIN wp_users
ON wp_postmeta.meta_key = '_customer_user'
AND wp_users.ID = wp_postmeta.meta_value
INNER JOIN wp_usermeta
ON wp_usermeta.user_id = wp_users.ID
INNER JOIN wp_woocommerce_order_items
ON wp_woocommerce_order_items.order_id = wp_posts.ID
INNER JOIN wp_woocommerce_order_itemmeta
ON wp_woocommerce_order_itemmeta.order_item_id = wp_woocommerce_order_items.order_item_id
WHERE wp_posts.post_type IN ('shop_order','shop_subscription')
GROUP BY wp_users.ID
It returns too large of a SUM of $340k instead of $4k, shown in second image here: https://imgur.com/a/mZs9Iej
Can anyone spot the error I made? Any help is appreciated!
try this one out
SELECT users.ID as userID,
posts.post_date,
posts.post_type,
users.user_email,
fname.meta_value as firstName,
lname.meta_value as lastName,
SUM(itemmeta.meta_value) as userTotal
FROM wp_posts posts
INNER JOIN wp_postmeta postmeta
ON postmeta.post_id = posts.ID
AND postmeta.meta_key = '_customer_user'
INNER JOIN wp_users users
ON users.ID = postmeta.meta_value
INNER JOIN wp_woocommerce_order_items items
ON items.order_id = posts.ID
INNER JOIN wp_woocommerce_order_itemmeta itemmeta
ON itemmeta.order_item_id = items.order_item_id
AND itemmeta.meta_key = '_line_total'
LEFT JOIN wp_usermeta fname
ON fname.user_id = users.ID
AND fname.meta_key = 'billing_first_name'
LEFT JOIN wp_usermeta lname
ON lname.user_id = users.ID
AND lname.meta_key = 'billing_last_name'
WHERE posts.post_type IN ('shop_order','shop_subscription')
GROUP BY users.ID
I introduced aliases for the tables and replaced your case constructs with left joins.
It seems that you need to specify the meta_keys as conditions because otherwise you will join rows that will not match the meta_key. This in turn will multiply the joined rows from wp_woocommerce_order_itemmeta and therefore the attributes you want to sum up.

SQL SUM columns from different tables

Good Afternoon,
I currently have the query:
SELECT erp_user.login,
SUM(invoice_header.invoice_amount) as 'Invoices Billed'
FROM erp_user
LEFT JOIN order_header ON erp_user.erp_user_id = order_header.req_by
LEFT JOIN invoice_instruct_header ON order_header.order_id = invoice_instruct_header.order_id
LEFT JOIN invoice_header ON invoice_instruct_header.instruct_id = invoice_header.instruct_no
WHERE erp_user.supervisor_id IS NOT NULL AND user_id_type = 'I' AND erp_user.company_id IS NOT NULL AND erp_user.is_active = 1
GROUP BY erp_user.login
It gives me a list of total billing in our system by employee where the employee is signed to a job on the job header.
I would love to add the total amount of open PO's to this query so I added:
SELECT erp_user.login, SUM(invoice_header.invoice_amount) as 'Invoices Billed', sum(po_header.po_amount) AS "Open PO's"
FROM erp_user
LEFT JOIN order_header ON erp_user.erp_user_id = order_header.req_by
LEFT JOIN invoice_instruct_header ON order_header.order_id = invoice_instruct_header.order_id
LEFT JOIN invoice_header ON invoice_instruct_header.instruct_id = invoice_header.instruct_no
LEFT JOIN po_header ON order_header.order_id = po_header.order_id
WHERE erp_user.supervisor_id IS NOT NULL AND user_id_type = 'I' AND erp_user.company_id IS NOT NULL AND erp_user.is_active = 1 AND po_header.status = 1
GROUP BY erp_user.login
ORDER BY "Open PO's"
That query gives me numbers in my Open PO's column, but they are incorrect and I'm at the point now where I can't figure out how to troubleshoot this.
Can someone please point me in the right direction? I don't mind doing the work, just need a pointer. Thanks!
Please be aware of conbination of Left join and Where clause.
SELECT erp_user.login
, SUM(invoice_header.invoice_amount) as 'Invoices Billed'
, sum(CASE WHEN po_header.status = 1 THEN po_header.po_amount ELSE 0 END) AS "Open PO's"
FROM erp_user
LEFT JOIN order_header ON erp_user.erp_user_id = order_header.req_by
LEFT JOIN invoice_instruct_header ON order_header.order_id = invoice_instruct_header.order_id
LEFT JOIN invoice_header ON invoice_instruct_header.instruct_id = invoice_header.instruct_no
LEFT JOIN po_header ON order_header.order_id = po_header.order_id
WHERE erp_user.supervisor_id IS NOT NULL
AND user_id_type = 'I'
AND erp_user.company_id IS NOT NULL
AND erp_user.is_active = 1
GROUP BY erp_user.login
ORDER BY "Open PO's";
If po_header joins to order_header, then in your original query it would be repeating each po_header for each invoice_header as well (leading to the incorrect calculation).
You could use outer apply() like so:
select
erp_user.login
, [Invoices Billed] = sum(invoice_header.invoice_amount)
, x.[Open POs]
from erp_user
left join order_header
on erp_user.erp_user_id = order_header.req_by
left join invoice_instruct_header
on order_header.order_id = invoice_instruct_header.order_id
left join invoice_header
on invoice_instruct_header.instruct_id = invoice_header.instruct_no
outer apply (
select
[Open POs] = sum(po_header.po_amount)
from po_header p
inner join order_header oh
on oh.order_id = p.order_id
where oh.req_by = erp_user.erp_user_id
) x
where erp_user.supervisor_id is not null
and erp_user.company_id is not null
and erp_user.is_active = 1
and user_id_type = 'I'
group by erp_user.login

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

SQL JOIN STRUGGLE

SELECT Count(TRK.REACTIE_ID),
S.UITGEVER,
S.NAAM,
S.BESCHRIJVING,
S.AFBEELDING_BESTANDSPAD,
S.SUBTITLE,
C.NAAM
FROM CATEGORIEEN_KOPPELTABEL CK
LEFT OUTER JOIN CATEGORIE C
ON C.CATEGORIE_ID = CK.CATEGORIE_ID
LEFT OUTER JOIN TV_SHOW S
ON S.TV_SHOW_ID = CK.TV_SHOW_ID
AND S.NAAM = 'South Park'
FULL OUTER JOIN TVSHOW_REACTIES_KOPPELTABEL TRK
ON TRK.TV_SHOW_ID = S.TV_SHOW_ID
GROUP BY TRK.TV_SHOW_ID,
S.UITGEVER,
S.NAAM,
S.BESCHRIJVING,
S.AFBEELDING_BESTANDSPAD,
S.SUBTITLE,
C.NAAM;
I can't figure out why I can't get only the first row back.
Now I get three rows back with null values and I want only to get the first row. Please help!
rows without nulls use the following FROM statement and keep the rest of query the same.:
FROM CATEGORIEEN_KOPPELTABEL CK
JOIN CATEGORIE C ON C.CATEGORIE_ID = CK.CATEGORIE_ID
JOIN TV_SHOW S ON S.TV_SHOW_ID = CK.TV_SHOW_ID AND S.NAAM = 'South Park'
JOIN TVSHOW_REACTIES_KOPPELTABEL TRK ON TRK.TV_SHOW_ID = S.TV_SHOW_ID