Compare amounts of two fields and compare it with third filed and return the result - sql

I have an scenario where I need to compare amounts based on their Code type and compare that amount with another code type and return the result.
For example:
SELECT distinct P.TERM_KEY, C.Country_code, Amt.DAMT
FROM TERM P
INNER JOIN Country C ON P.TERM_KEY= C.TERM_KEY
INNER JOIN Amount Amt ON C.COU_KEY = Amt.PARENT_KEY AND Amt.PARENT_TABLE=Country
WHERE P.Term_no = 'ABCD' AND C.Country_CD IN (50, 51)
and result of this query is below:
TERM_KEY Country_code DAMT
201000000085 5000 1000.00
201000000083 5001 750.00
201000000081 5001 1000.00
201000000342 5000 1000.00
201000002340 5001 750.00
201000034733 5001 1000.00
Now I need to compare the Damt of country codes (50 and 51) with Country code 20, if Damt of country code 20 and Country Codes (50 , 51) are equal I need to report value as '5869', else if not equal I need to report value as '0000'.
I'll use the above result set in some other case condition
Example
Case
WHEN C.County = 999 and C.Contry_code = '20' AND ISNULL(CDED.DAmt,0)=0 THEN '5869'
C.County = 999 and C.Contry_code = '20' AND ISNULL(Amt.DAmt,0)!=0 THEN '0000'
end as Country_County
So CDED has to return the result set which I need to use in case. How can that be done?

Not sure what your data looks like or how it's related, but i would just create 2 sub-queries and join them.
select case
when ISNULL(subset_5051.DAmt,0) = ISNULL(subset_20.DAmt,0) then '5869'
else '0000'
end
from
(
SELECT distinct P.TERM_KEY, C.Country_code, Amt.DAMT
FROM TERM P
INNER JOIN Country C ON P.TERM_KEY= C.TERM_KEY
INNER JOIN Amount Amt ON C.COU_KEY = Amt.PARENT_KEY AND Amt.PARENT_TABLE=Country
WHERE P.Term_no = 'ABCD' AND C.Country_CD IN (50, 51)
) as subset_5051
[left / right / inner / full] join
(
SELECT distinct P.TERM_KEY, C.Country_code, Amt.DAMT
FROM TERM P
INNER JOIN Country C ON P.TERM_KEY= C.TERM_KEY
INNER JOIN Amount Amt ON C.COU_KEY = Amt.PARENT_KEY AND Amt.PARENT_TABLE=Country
WHERE P.Term_no = 'ABCD' AND C.Country_CD IN (20)
) as subset_20
on subset_5051.[?] = subset_20.[?]
i don't know what type of join you should use, or what columns to join on, but that should get you started.

Related

SQL how sum if value

Hi I try to need to sum values and if there is more than 20 there shouldbe written 20 else should be number.
I don't know what i make wrong:
SELECT
ta6.product_product_id AS ID,
ta6.product_manufacture_code AS Code,
SUM(CASE WHEN ta3.stock_quantity >= 20 THEN 20 ELSE ta3.stock_quantity END) AS Quantity,
ta4.price_value AS Price,
ta5.Attribute_Value AS Sizer,
ta6.Procut_product_name AS Name,
ta7.Attribute_Value AS produce
FROM
product ta6
LEFT JOIN stock ta3 ON
ta3.stock_id = ta6.product_id
LEFT JOIN price ta4 ON
ta4.price_id = ta6.product_id
AND ta4.price_type = 2
LEFT JOIN Attributes ta5 ON
ta5.Attributes_product_Id = ta6.product_id
LEFT JOIN Attributes ta7 ON
ta7.Attributes_product_Id = ta6.product_id
WHERE
( ta3.stock_wharehouse_id = 1
AND ta5.Attrib_id = 54
AND ta7.Attrib_id = 25 )
GROUP BY
ta6.product_manufacture_code,
ta6.product_product_id
ta4.price_value,
ta5.Attribute_Value,
ta6.product_product_name ,
ta7.Attribute_Value;
Table stock_quantity looks like:
Stock_table image
How to sum it ??
Like this?
CASE WHEN SUM(ta3.stock_quantity) >= 20
THEN 20
ELSE SUM(ta3.stock_quantity)
END AS Quantity

How to pull unrelated data in a column from two tables.?

I have following two tables:
BenPlan
BenPlanId BenPlanName BenPlanRate EmployeeCost
-----------------------------------------------------
1 Medical 0.45 5000
2 Dental 0.75 2000
EmployeeBenPlan
EmployeeId BenPlanId EffectiveStart EffectiveEnd
-------------------------------------------------------
1 1 1/1/2019 NULL
2 2 1/1/2019 NULL
Now, I have to make a report which shows data as under:
EmployeeBenPlanDetails
EmployeeId BenPlanName Rate EmployeeCost EffectiveStart EffectiveEnd
--------------------------------------------------------------------------------
1 Medical 0.75 5000 1/1/2019 NULL
2 Dental 0.75 2000 1/1/2019 NULL
That is, even when the ben plan is medical, I need to show the rate for Dental plan in the Rate column, or should I say, the rate column should display the result of following query:
SELECT Rate
FROM BenPlan
WHERE BenPlanName = 'Dental'
How can we do this?
Well, the following query returns your expected result. It always returns Rate of the Dental plan.
SELECT
EmployeeBenPlan.EmployeeId
,BenPlan.BenPlanName
,(
SELECT Rate
FROM BenPlan
WHERE BenPlanName = 'Dental'
) AS Rate
,BenPlan.EmployeeCost
,EmployeeBenPlan.EffectiveStart
,EmployeeBenPlan.EffectiveEnd
FROM
EmployeeBenPlan
INNER JOIN BenPlan ON BenPlan.BenPlanId = EmployeeBenPlan.BenPlanId
;
If the table BenPlan can have more than one row where BenPlanName = 'Dental', then you should somehow pick a single row. You can add TOP(1) with a suitable ORDER BY to the subquery.
SELECT TOP(1) Rate
FROM BenPlan
WHERE BenPlanName = 'Dental'
ORDER BY BenPlanId
You can use the following solution. This solution also works in case you are adding new records on BenPlan:
SELECT ebp.EmployeeId, bp.BenPlanName, bp.BenPlanRate AS Rate, bp.EmployeeCost, ebp.EffectiveStart, ebp.EffectiveEnd
FROM EmployeeBenPlan ebp INNER JOIN (
SELECT b1.BenPlanId, b1.BenPlanName, b1.EmployeeCost,
CASE WHEN b1.BenPlanName = 'Medical' THEN b2.BenPlanRate ELSE b1.BenPlanRate END AS BenPlanRate
FROM BenPlan b1 LEFT JOIN BenPlan b2 ON b1.BenPlanName = 'Medical' AND b2.BenPlanName = 'Dental'
) bp ON ebp.BenPlanId = bp.BenPlanId
ORDER BY ebp.EmployeeId, ebp.BenPlanId
demo on dbfiddle.uk
you can write this query
SELECT E.EmployeeId,B.BenPlanName,(SELECT TOP(1) Rate
FROM BenPlan
WHERE BenPlanName = 'Dental') AS Rate,
B.EmployeeCost,E.EffectiveStart,E.EffectiveEnd
FROM BenPlan B
INNER JOIN EmployeeBenPlan E ON B.BenPlanId = E.BenPlanId
You seem to want two joins to benplan, one just for "Dental" and one for the name of the actual plan:
select ebp.EmployeeId, bp.BenPlanName,
bpd.Rate, bp.EmployeeCost,
ebp.EffectiveStart, epb.EffectiveEnd
from employeebenplan ebp join
benplan bp
on ebp.BenPlanId = bp.BenPlanId join
benplan bpd
on bpd.BenPlanName = 'Dental'

How to sum a count of bookings to display total bookings for location and total value for location

I am writing a report that needs to show the number of bookings taken for a location with the total value of those bookings.
How do I sum the bookings column and show only one row for the location, that includes the columns set out in the example of expected data?
Select Statement Below:
SELECT
Locations.Description as LocationsDesc,
Locations.LocationGUID,
Venues.VenueName,
Venues.VenueGUID,
count (Bookings.BookingID) as Bookings,
Departments.DepartmentName,
Departments.DepartmentGUID,
sum(SalesTransactionDetails.NetDetailValue) as NetDetailValue,
sum(SalesTransactionDetails.DetailValue) as DetailValue,
SUM(CASE When Salestransactionlines.itemtype = 1 Then SalesTransactionDetails.NetDetailValue Else 0 End ) as RentalFee,
SUM(CASE When Salestransactionlines.itemtype = 2 Then SalesTransactionDetails.NetDetailValue Else 0 End ) as ExtraFee,
SalesTransactions.SalesTransactionGUID
FROM BookingLinesDetails
INNER JOIN Bookings ON BookingLinesDetails.BookingGUID=Bookings.BookingGUID
INNER JOIN Locations ON BookingLinesDetails.LocationGUID=Locations.LocationGUID
INNER JOIN Venues on Venues.Venueguid = Locations.Venueguid
INNER JOIN SalesTransactionDetails ON BookingLinesDetails.BookingLinesDetailGUID=SalesTransactionDetails.BookingLinesDetailGUID
INNER JOIN SalesTransactionLines ON SalesTransactionDetails.SalesTransactionLineGUID=SalesTransactionLines.SalesTransactionLineGUID
INNER JOIN SalesTransactions ON SalesTransactionLines.SalesTransactionGUID=SalesTransactions.SalesTransactionGUID
INNER JOIN Departments on Departments.DepartmentGUID = Locations.DepartmentGUID
WHERE
BookingLinesDetails.StartDateTime >= dbo.InzDateOnly(#pFromDate) and
BookingLinesDetails.StartDateTime < DateAdd(day,1,dbo.inzDateOnly(#pToDate)) and
Departments.DepartmentGUID in (Select GUID from dbo.InzSplitGUID(#DepartmentID)) and
(#IncludeAllLocationGroupsInVenues <> 0 or (#IncludeAllLocationGroupsInVenues = 0 )) and
Venues.VenueGUID in (Select GUID from dbo.InzSplitGUID(#VenueID)) and
salesTransactions.Status = 1 and -- remove cancelled
salestransactions.receiptonly = 0
GROUP BY
Locations.Description,
Locations.LocationGUID,
Venues.VenueName,
Venues.VenueGUID,
Departments.DepartmentName,
Departments.DepartmentGUID,
SalesTransactions.SalesTransactionGUID
The output is currently:
Desired output is:
LocationsDesc LocationGUID VenueGUID Bookings DepartmentName NetDetailValue DetailValue ExtraFee
Location - Deck Room 348A43F12 7DAD77BE 33 Aquatics Centre 2059.46 2162.5 0
I have attempted several versions of Count and sum. I believe I need to make the query a derived table and then select from that, but am not sure how to go about it, even if that is the answer.
Thank you in advance.

Sum Values within 3 tables

Table 1
jh."job-hdr"
job-date job-disp job-dept job-route job-id job-no
01/04/2013 6467 abc 123 22 81088
01/04/2013 6468 abc 987 36 82568
Table 2
rh."rec-charge"
charge-type rec-id base-sales-value
XYZ 22 700
Table 3
rc."rec-cost"
charge-type rec-id base-cost-value
XYZ 22 300
I need to be able to get the profit from this jobid of
700 - 300 = 400
This is where I have gotten up to
SELECT jh."job-date", jh."job-disp", jh."job-dept", jh."job-route", rc."charge-type",rh."charge-type",
SUM(rc."base-cost-value") as COSTS,
SUM(rh."base-sales-value") as SALES,
SUM(rh."base-sales-value") - SUM(rc."base-cost-value") as PROFIT
FROM MSN.PUB."rec-chg" rh, PUB."job-hdr" jh, pub."rec-cost" rc
WHERE jh."job-date" between '2013-04-01' and '2013-04-30'
and jh."job-id" = rc."rec-id"
and rc."rec-id" = rh."rec-id"
and jh."grp-id" = '0'
and jh."job-status"<>'D'
and jh."job-no" = '81088'
and rc."charge-type" = rh."charge-type"
Group by jh."job-date", jh."job-disp", jh."job-dept", jh."job-route",rc."charge- type",rh."charge-type"
This is not giving me great results at all and I know I am way off. I just need to be put in the right direction.
Update profit to:
SUM(rh."base-sales-value" - rc."base-cost-value") as PROFIT
And update your group by to:
group by jh."job-id", rc."rec-id", rh."rec-id"
This should give your the desired result (hopefully). Sorry didnt not have time to test it myself. The main focus is on group by, which should be applied on a field that would return multiple results for other fields you want to run the sum on.
Your question appears is a little ambiguous, as to whether you want the results by job or by charge type. In either case, you need to aggregate the results before doing the join. The following query does this at the job level:
SELECT jh."job-date", jh."job-disp", jh."job-dept", jh."job-route",
COSTS, SALES, SALES - COSTS as PROFIT
FROM PUB."job-hdr" jh left outer join
(select rh."rec-id", SUM(rh."base-sales-value") as SALES
from MSN.PUB."rec-chg" rh
group by rh."rec-id"
) rh
on jh."job-id" = rh."rec-id" left outer join
(select rc."rec-id", SUM(rc."base-cost-value") as COSTS
from pub."rec-cost" rc
group by rc."rec-id"
) rc
on jh."job-id" = rc."rec-id"
WHERE jh."grp-id" = '0' and
jh."job-status" <> 'D' and
jh."job-no" = '81088';
Notice that I replaced your implicit join syntax with explicit join syntax. The explicit version is much better, so you should learn to use it.

Get percentages of larger group

The query below is kind of an ugly one so I hope I've got it spaced well enough to make it readable. The query finds the percentage of people that visit a given hospital if they are from a certain area. For instance, if 100 people live in county X and 20 go to hospital A and 80 go to hospital B the query outputs. How the heck is this sort of thing done? Let me know if I need to document the query or whatever I can do to make it clearer.
hospital A 20
hospital B 80
The query below works exactly like I want it to, but it give me thinking: how could this be done for every county in my table?
select hospitalname, round(cast(counts as float)/cast(fayettestrokepop as float)*100,2)as percentSeen
from
(
SELECT tblHospitals.hospitalname, COUNT(tblHospitals.hospitalname) AS counts, tblStateCounties_1.countyName,
(SELECT COUNT(*) AS Expr1
FROM Patient INNER JOIN
tblStateCounties ON Patient.stateCode = tblStateCounties.stateCode AND Patient.countyCode = tblStateCounties.countyCode
WHERE (tblStateCounties.stateCode = '21') AND (tblStateCounties.countyName = 'fayette')) AS fayetteStrokePop
FROM Patient AS Patient_1 INNER JOIN
tblHospitals ON Patient_1.hospitalnpi = tblHospitals.hospitalnpi INNER JOIN
tblStateCounties AS tblStateCounties_1 ON Patient_1.stateCode = tblStateCounties_1.stateCode AND Patient_1.countyCode = tblStateCounties_1.countyCode
WHERE (tblStateCounties_1.stateCode = '21') AND (tblStateCounties_1.countyName = 'fayette')
GROUP BY tblHospitals.hospitalname, tblStateCounties_1.countyName
) as t
order by percentSeen desc
EDIT: sample data
The sample data below is without the outermost query (the as t order by part).
The countsInTheCounty column is the (select count(*)..) part after 'tblStateCounties_1.countyName'
hospitalName hospitalCounts countyName countsInTheCounty
st. james 23 X 300
st. jude 40 X 300
Now with the outer query we would get
st james 0.076 (23/300)
st. jude 0.1333 (40/300)
Here is my guess. You'll have to test against your data or provide proper DDL + sample data.
;WITH totalCounts AS
(
SELECT StateCode, countyCode, COUNT(*) AS totalcount
FROM dbo.Patient GROUP BY StateCode, countyCode
)
SELECT
h.hospitalName,
hospitalCounts = COUNT(p.hospitalnpi),
c.countyName,
countsInTheCounty = tc.totalCount,
percentseen = CONVERT(DECIMAL(5,2), COUNT(p.hospitalnpi)*100.0/tc.totalCount)
FROM
dbo.Patient AS p
INNER JOIN
dbo.tblHospitals AS h
ON p.hospitalnpi = h.hospitalnpi
INNER JOIN
totalCounts AS tc
ON p.StateCode = tc.StateCode
AND p.countyCode = tc.countyCode
INNER JOIN
dbo.tblStateCounties AS c
ON tc.StateCode = c.stateCode
AND tc.countyCode = c.countyCode
GROUP BY
h.hospitalname,
c.countyName,
tc.totalcount
ORDER BY
c.countyName,
percentseen DESC;