Get invoice that has sales order and invoice without Sales Order - sql-server-2008

I want to achieve the following query.
What i want here is to compare the Invoice Amount from the Sales so the fields that i'll be needing are these:
OSLP.SalesPerson|OINV.CardName|OINV.DocDate|OINV.DocNum|OINV.DocTotal|ORDR.DocDate|ORDR.DocTotal|OINV.GrosProfit
What i have done so far is this,
Declare #mindate date = '10.01.16', #maxdate date = '10.31.16'
SELECT DISTINCT
T6.SlpName [Sales Person],
T5.CardName [Customer Name],
T5.DocDate [TRA Date],
T5.DocNum [TRA No],
T5.DocTotal [TRA Total],
(SELECT SUM(T8.DocTotal) FROM ORIN T8 INNER JOIN RIN1 T9 ON T8.DocEntry=T9.DocEntry WHERE T8.DocDate BETWEEN #mindate AND #maxdate) [Credit Amnt],
T1.DocDate [SO Date],
T1.DocTotal [SO Total],
T5.GrosProfit [Gross Profit]
FROM RDR1 T0
INNER JOIN ORDR T1 ON T0.DocEntry = T1.DocEntry
left outer JOIN DLN1 T2 on T2.BaseEntry = T0.DocEntry
left outer JOIN ODLN T3 on T2.DocEntry = T3.DocEntry
left Outer JOIN INV1 T4 on T4.BaseEntry = T3.DocEntry AND T4.BaseLine = T2.Linenum AND T4.BaseType = 15
OR (T4.Basetype=17 and T4.BaseEntry=T0.DocEntry AND T4.BaseLine=T0.LineNum)
left outer JOIN OINV T5 on T5.DocEntry = T4.DocEntry
left outer JOIN OSLP T6 on T6.SlpCode = T1.SlpCode
WHERE T5.DocDate BETWEEN #mindate AND #maxdate
Group by
T6.SlpName, T5.CardName, T1.CardCode,
T5.DocDate, T5.DocNum, T5.DocTotal,
T1.DocDate, T1.DocTotal, T5.GrosProfit
ORDER BY
T5.CardName, T5.DocDate
As you can i see, i included the ORIN(Credit Memo) table to deduct the SUM of OINV.DocTotal with ORIN.DocTotal.
So, this query works as it's suppose to be BUT, I am not able to get those invoices that has no related documents like Sales order or Delivery. Solely, it's just invoice.

Related

How can i eliminate duplicate data when joining 2 queries via union?

i have 2 queries that pull same fields with only diff is what the subquery in the where clause returns.
first query pulls based on the code and insurance_group_name
SELECT
cpt_codes.code,
ii.insurance_group_name,
ii.insurance_group_id,
CAST(AVG(dcc_total_view.allowedAmount) AS decimal(10, 2)) `AVG Allowed by Group Name`,
CAST(AVG(rc_total_view.runningCollectedReceivedByProvider) AS decimal(10, 2)) `AVG Collected by Group Name`,
GROUP_CONCAT(DISTINCT file_acceptance) AS `FAN`
FROM ds
LEFT OUTER JOIN dd
ON ds.dos_detail_id = dd.id
LEFT OUTER JOIN ii
ON ds.ii_id = ii.id
LEFT OUTER JOIN dcc
ON ds.id = dcc.dos_id
LEFT OUTER JOIN cpt_codes
ON dcc.cpt_id = cpt_codes.id
LEFT OUTER JOIN bi
ON ds.billing_id = bi.id
LEFT OUTER JOIN cs
ON bi.claim_status = cs.id
LEFT OUTER JOIN rc_total_view
ON ds.payment_information_id = rc_total_view.id
LEFT OUTER JOIN dcc_total_view
ON ds.id = dcc_total_view.dos_id
WHERE (cpt_codes.code, ii.insurance_group_name) IN (SELECT
cpt_codes.code,
ii.insurance_group_name
FROM ds
LEFT OUTER JOIN dd
ON ds.dos_detail_id = dd.id
LEFT OUTER JOIN ii
ON ds.ii_id = ii.id
LEFT OUTER JOIN dcc
ON ds.id = dcc.dos_id
LEFT OUTER JOIN cpt_codes
ON dcc.cpt_id = cpt_codes.id
LEFT OUTER JOIN bi
ON ds.billing_id = bi.id
LEFT OUTER JOIN cs
ON bi.claim_status = cs.id
WHERE cs.status = 'Pending'
AND date_of_service BETWEEN '2017/01/01' AND '2018/08/31'
AND (dcc.rev_code = '0490'
OR dcc.rev_code = '0360'))
AND date_of_service BETWEEN '2017/01/01' AND '2018/08/31'
AND (dcc.rev_code = '0490'
OR dcc.rev_code = '0360')
AND dcc_total_view.allowedAmount > 0
GROUP BY code ,insurance_group_name
this would return a line like this
code
insurance_group_name
insurance_group_id
AVG Allowed by Group Name
AVG Collected by Group Name
FAN
20553
AE
215825
1440.97
889.48
DELA081518,MOLDGILR919,SHIC060618,MANS072718,DELA053018,DELS072518
the Second one pulls based on insurance_group_id
SELECT
cpt_codes.code,
ii.insurance_group_name,
ii.insurance_group_id,
CAST(AVG(dcc_total_view.allowedAmount) AS decimal(10, 2)) `AVG Allowed by Group Name`,
CAST(AVG(rc_total_view.runningCollectedReceivedByProvider) AS decimal(10, 2)) `AVG Collected by Group Name`,
GROUP_CONCAT(DISTINCT file_acceptance) AS `FAN`
FROM ds
LEFT OUTER JOIN dd
ON ds.dos_detail_id = dd.id
LEFT OUTER JOIN ii
ON ds.ii_id = ii.id
LEFT OUTER JOIN dcc
ON ds.id = dcc.dos_id
LEFT OUTER JOIN cpt_codes
ON dcc.cpt_id = cpt_codes.id
LEFT OUTER JOIN bi
ON ds.billing_id = bi.id
LEFT OUTER JOIN cs
ON bi.claim_status = cs.id
LEFT OUTER JOIN rc_total_view
ON ds.payment_information_id = rc_total_view.id
LEFT OUTER JOIN dcc_total_view
ON ds.id = dcc_total_view.dos_id
WHERE (cpt_codes.code, ii.insurance_group_id) IN (SELECT
cpt_codes.code,
ii.insurance_group_id
FROM ds
LEFT OUTER JOIN dd
ON ds.dos_detail_id = dd.id
LEFT OUTER JOIN ii
ON ds.ii_id = ii.id
LEFT OUTER JOIN dcc
ON ds.id = dcc.dos_id
LEFT OUTER JOIN cpt_codes
ON dcc.cpt_id = cpt_codes.id
LEFT OUTER JOIN bi
ON ds.billing_id = bi.id
LEFT OUTER JOIN cs
ON bi.claim_status = cs.id
WHERE cs.status = 'Pending'
AND date_of_service BETWEEN '2017/01/01' AND '2018/08/31'
AND (dcc.rev_code = '0490'
OR dcc.rev_code = '0360'))
AND date_of_service BETWEEN '2017/01/01' AND '2018/08/31'
AND (dcc.rev_code = '0490'
OR dcc.rev_code = '0360')
AND dcc_total_view.allowedAmount > 0
GROUP BY code ,insurance_group_id
this would return a line like
code
insurance_group_name
insurance_group_id
AVG Allowed by Group Name
AVG Collected by Group Name
FAN
20553
AE
10198703100012
250.25
150.36
MOLDGILR919
when doing union on these 2 i find some data is duplicated where the FAN # that the second query returns is included in the output from the first as you can see the FAN# is part of the ones that make up the results of the first script.
how can i join together the results of these 2 queries and make sure if the FAN# in the second is already included in results from the first for a given code (like 20553 in the example) then that row from the second will not be included in the final output ?
I hope i have included enough info and detail to help me out here, I really appreciate any help to figure this out.
Put the output of your first statemen in a temporary table, lets name that #temp1, and the output of your second query in a temporary table named #temp2.
After that you can do:
SELECT *
FROM #temp1
UNION ALL
SELECT *
FROM #temp2
WHERE code NOT IN (SELECT code FROM #temp1)
EDIT: Because of the FAN problem..
I think you should change your queries, in this way:
Do not use GROUP_CONCAT(...) to combine the results of different FAN's in one row, and add file_acceptance to the GROUP BY-clause
This way you will get indivdual records for every FAN, annd, after the UNION ALL you can GROUP_CONCAT() then again.
This might need some more think/tweak work because of the AVG() fields....

Count based on another count - MySQL

I have the following Set of tables and I want to get all the services, age ranges and genders and next to each three of them the count of recipients corresponding to them.
So far I came up with the statement below, and it works.
select s.service_name,s.service_id,g.gender_id,ag.age_range_id,count(r.recipient_id) Temp
from tbl_services s inner join tbl_gender g
inner join tbl_age_range ag
left join tbl_recipient_services rs on rs.service_id=s.service_id
left join tbl_recipient r on r.gender_id=g.gender_id and rs.recipient_id=r.recipient_id
and (year(sysdate())-year(r.recipient_birth_date) >= min_age and year(sysdate())-year(r.recipient_birth_date) <= max_age)
group by s.service_id,g.gander_id,ag.age_range_id
But I need to only count the recipients who have 2 or more services in the tbl_recipient_services and I'm stuck again.
Anyone has an idea to fix that?
First, your query would be clearer with cross joins:
select s.service_name, s.service_id, g.gender_id, ag.age_range_id,
count(r.recipient_id) as all_recipients
from tbl_services s cross join
tbl_gender g cross join
tbl_age_range ag left join
tbl_recipient_services rs
on rs.service_id = s.service_id left join
tbl_recipient r
on r.gender_id = g.gender_id and
rs.recipient_id = r.recipient_id and
year(sysdate()) - year(r.recipient_birth_date) >= min_age and
year(sysdate()) - year(r.recipient_birth_date) <= max_age)
group by s.service_id, g.gender_id, ag.age_range_id;
This returns all combinations of service/gender/age even if there are no matches.
Let's add another column. To do so, we'll use a subquery to count the number of services per recipient and then include that in the count:
select s.service_name, s.service_id, g.gender_id, ag.age_range_id,
count(r.recipient_id) as num_recipients,
sum(rs2.num_services >= 2) as num_recipients_2plus
from tbl_services s cross join
tbl_gender g cross join
tbl_age_range ag left join
tbl_recipient_services rs
on rs.service_id = s.service_id left join
tbl_recipient r
on r.gender_id = g.gender_id and
rs.recipient_id = r.recipient_id and
year(sysdate()) - year(r.recipient_birth_date) >= min_age and
year(sysdate()) - year(r.recipient_birth_date) <= max_age) left join
(select rs2.recipient_id, count(*) as num_services
from tbl_recipient_services rs2
group by rs2.recipient_id
) rs2
on rs2.recipient_id = r.recipient_id
group by s.service_id, g.gender_id, ag.age_range_id;
If you don't want the additional column, you can change the left joins to inner joins and remove the count(r.recipient_id).

GROUP BY from inner SELECT suquery is ignored in column sum

I have following query
SELECT YEAR(T.date), MONTH(T.date), T.production, T.lineID, SUM(rework + scrap)
FROM
(SELECT MAX(positionID), date, production, lineID
FROM productionPerPosition
WHERE lineID = 2
AND date BETWEEN '2017-01-01' AND '2017-01-31'
GROUP BY date) AS T
INNER JOIN linePosition lp ON lp.lineID = T.lineID
INNER JOIN fttErrorType fet ON fet.positionID = lp.positionID
INNER JOIN fttData fd ON fd.errorID = fet.errorID
AND fd.date = T.date
GROUP BY YEAR(T.date), MONTH(T.date)
which gives this result
Now, I would like to group these results by year and month to get sum of production and sum of last column. I've tried this query
SELECT YEAR(T.date), MONTH(T.date), SUM(T.production), T.lineID, SUM(rework + scrap)
FROM
(SELECT MAX(positionID), date, production, lineID
FROM productionPerPosition
WHERE lineID = 2
AND date BETWEEN '2017-01-01' AND '2017-01-31'
GROUP BY date) AS T
INNER JOIN linePosition lp ON lp.lineID = T.lineID
INNER JOIN fttErrorType fet ON fet.positionID = lp.positionID
INNER JOIN fttData fd ON fd.errorID = fet.errorID
AND fd.date = T.date
GROUP BY YEAR(T.date), MONTH(T.date)
Which gives me
Here production sum is wrong! It seems that GROUP BY from 7th line in first query is ignored.
Any idea how could I get needed result?
Edit: In inner SELECT I have separate production for several different positions (positionID) but I'm using only production from position that has highest positionID
Group has missing grouping columns that why it is resulting in some unexpected result
SELECT YEAR(T.date), MONTH(T.date), SUM(T.production), T.lineID, SUM(rework + scrap)
FROM
(SELECT MAX(positionID), date, production, lineID
FROM productionPerPosition
WHERE lineID = 2
AND date BETWEEN '2017-01-01' AND '2017-01-31'
GROUP BY date, production, lineID) AS T
INNER JOIN linePosition lp ON lp.lineID = T.lineID
INNER JOIN fttErrorType fet ON fet.positionID = lp.positionID
INNER JOIN fttData fd ON fd.errorID = fet.errorID
AND fd.date = T.date
GROUP BY YEAR(T.date), MONTH(T.date), T.lineID
Has explained in e4c5 comment, you have to add all the unaggregated fields to your GROUP BY. I made it in the inner SELECT and in the main SELECT:
SELECT YEAR(T.date), MONTH(T.date), SUM(T.production), T.lineID, SUM(rework + scrap)
FROM
(SELECT MAX(positionID), date, production, lineID
FROM productionPerPosition
WHERE lineID = 2
AND date BETWEEN '2017-01-01' AND '2017-01-31'
GROUP BY date, production, lineID) AS T
INNER JOIN linePosition lp ON lp.lineID = T.lineID
INNER JOIN fttErrorType fet ON fet.positionID = lp.positionID
INNER JOIN fttData fd ON fd.errorID = fet.errorID
AND fd.date = T.date
GROUP BY YEAR(T.date), MONTH(T.date), T.lineID

multiple table join to generate report counts

I am trying to generate a report that will display data from 3 tables as follows:
SELECT B.datepoll, B.clientID, B.badTerm, A.FullQuery,
B.badMessage, C.clientNAME, E.CURRENT_TERMS
FROM BadTerms AS B INNER JOIN
QueryTERMS AS A ON B.badTerm = A.QUERIES INNER JOIN
Clients AS C ON B.clientID = C.clientID INNER JOIN
(
SELECT CLIENTID,COUNT(QUERIES) AS CURRENT_TERMS FROM QueryTERMS WHERE
clientID = 'XXXXXX' GROUP BY CLIENTID) E ON
E.CLIENTID = A.CLIENTID
WHERE (CONVERT(VARCHAR(10), B.datepoll, 120) < CONVERT(VARCHAR(10), GETDATE(), 120))
AND (B.clientID = 'XXXXXX')
Basically what should be displayed is for a given datepoll, display all badTerms, fullQuery, badMessage, clientID, clientName and total terms. The clientID is common among all 3 tables and queries is common among BadTerms and QueryTerms.
I have everything fine except for the total count. It should only appear once and be the total queries in the QueryTerms table not the BadTerms table.
Any help appreciated.
Actually got it to work now:
SELECT B.datepoll, B.clientID, B.badTerm, A.FullQuery,
B.badMessage, C.clientNAME, E.CURRENT_TERMS
FROM BadTerms AS B INNER JOIN
QueryTERMS AS A ON B.badTerm = A.QUERIES INNER JOIN
Clients AS C ON B.clientID = C.clientID INNER JOIN
(
SELECT CLIENTID,COUNT(QUERIES) AS CURRENT_TERMS FROM QueryTERMS WHERE
clientID = 'XXXXXX' GROUP BY CLIENTID) E ON
E.CLIENTID = A.CLIENTID
WHERE (CONVERT(VARCHAR(10), B.datepoll, 120) < CONVERT(VARCHAR(10), GETDATE(), 120))
AND (B.clientID = 'XXXXXX')

Hanging mysql query

I'm having an issue with the following query
select
ord.order_id,
ordProduct.product_id,
coupProd.product_id,
coup.date_end as DateEnd, coup.coupon_id
from `order` ord
inner join order_product ordProduct on ord.order_id = ordProduct.order_id
inner join coupon_product coupProd on ordProduct.product_id = coupProd.product_id
inner join coupon coup on coupProd.coupon_id = coup.coupon_id
where (coup.date_end > curdate());
If I remvove the where clause, the query executes fine, otherwise it just hangs. Any ideas?
It's not a solution per se, but as a workaround, you could maybe get it done as a nested query. i.e. ,
SELECT * FROM (
SELECT
ord.order_id,
ordProduct.product_id,
coupProd.product_id,
coup.date_end AS DateEnd, coup.coupon_id
FROM `order` ord
INNER JOIN order_product ordProduct ON ord.order_id = ordProduct.order_id
INNER JOIN coupon_product coupProd ON ordProduct.product_id = coupProd.product_id
INNER JOIN coupon coup ON coupProd.coupon_id = coup.coupon_id)
WHERE (DateEnd > CURDATE());