Maximum value from column while rows have different fields - sql

I wrote following sql query
SELECT ST.Roll, CR.Code, CR.Title, CR.Credits, SCH.ObtainedGPA, SCH.Grade
FROM [MIU_UCAM.1.0.1].[dbo].[StudentCourseHistory] AS SCH
JOIN [MIU_UCAM.1.0.1].[dbo].[Student] AS ST ON SCH.StudentID = ST.StudentID
JOIN [MIU_UCAM.1.0.1].[dbo].[Course] AS CR ON SCH.CourseID = CR.CourseID AND SCH.VersionID = CR.VersionID
WHERE ST.Roll ='0914BPM00387'
It return result like following
Roll Code Title Credits ObtainedGPA Grade
0914BPM00387 BPM216 Physiology Lab - 1 4.00 A+
0914BPM00387 BPM217 Pharmaceutical Microbiology 3 2.25 C
0914BPM00387 BPM217 Pharmaceutical Microbiology 3 2.00 D
0914BPM00387 BPM218 Pharmaceutical Microbiology Lab 1 3.50 A-
Here BPM217 and BPM217 are same but it's ObtainedGrade is different, 2.25 and 2.00 and Grade is also different, C and D. Now how can I get only the column hat have maximum value 2.25.

How about using MAX on the ObtainedGPA and MIN on the GRADE:
SELECT ST.Roll, CR.Code, CR.Title, CR.Credits, MAX(SCH.ObtainedGPA), MIN(SCH.GRADE)
FROM [MIU_UCAM.1.0.1].[dbo].[StudentCourseHistory] AS SCH
JOIN [MIU_UCAM.1.0.1].[dbo].[Student] AS ST ON SCH.StudentID = ST.StudentID
JOIN [MIU_UCAM.1.0.1].[dbo].[Course] AS CR ON SCH.CourseID = CR.CourseID AND SCH.VersionID = CR.VersionID
WHERE ST.Roll ='0914BPM00387'
GROUP BY ST.Roll, CR.Code, CR.Title, CR.Credits

Try something like this.
SELECT ST.Roll,
CR.Code,
CR.Title,
CR.Credits,
(select MAX(SCH.ObtainedGPA)
from StudenCourseHistory s
where s.StudentID = ST.Student_ID
and s.CourseID = CR.CourseID),
SCH.Grade
FROM [MIU_UCAM.1.0.1].[dbo].[StudentCourseHistory] AS SCH
JOIN [MIU_UCAM.1.0.1].[dbo].[Student] AS ST ON SCH.StudentID = ST.StudentID
JOIN [MIU_UCAM.1.0.1].[dbo].[Course] AS CR ON SCH.CourseID = CR.CourseID AND SCH.VersionID = CR.VersionID
WHERE ST.Roll ='0914BPM00387'

Related

SQL Join Query for Solution for A(Table) selected and B(table) all Record

enter image description here
SELECT
TR.UserKeyCode, TR.ProductID, TR.Line_No
FROM
TBLT_RESULTDTL_DONE TR
LEFT OUTER JOIN
TBLM_PRODUCT TP ON TR.ProductID = TP.ProductID
WHERE
TR.UserKeyCode = 'E01_00001' AND TR.QustionID = 1
Result:
E01_00001 11 1
E01_00001 36 2
E01_00001 16 3
Product table all results and Result record 3 only i need others will be null
SELECT
TR.UserKeyCode, TR.ProductID, TR.Line_No
FROM
TBLM_PRODUCT TP
LEFT OUTER JOIN
TBLT_RESULTDTL_DONE TR ON TR.ProductID = TP.ProductID and TR.UserKeyCode = 'E01_00001' AND TR.QustionID = 1

Should I use a subquery or sum in this situation?

I am trying to get line 11 (which can have multiple results of square footage numbers of different areas of a house such as porches, garages and includes living area) and subtract line 10 if possible to get the total square footage of areas in a house other than living area.
as a-- sum(id1.[calc_area] - pp.living_area) as [other_ area],
my problem is the two numbers are from different tables, and the select statement uses a different from table pv. What would be the easiest way to accomplish this?
select distinct pv.prop_id,
pv.hood_cd as neighborhood,
pv.abs_subdv_cd as subdivision,
cast (pv.[legal_desc] as char(16)) as legal,
[deed_date],
[consideration],
pv.prop_val_yr as year,
sts1.[situs_num] as address,
cast(sts1.[situs_street] as char(11)) as street,
pp.living_area,
id1.[calc_area] as [total_area],
cast (pp.[land_total_acres]as decimal (6,2))as acres,
[sale_type],
case when [sale_date] >='01/01/2014'then convert(varchar(18), [sale_date], 101)else''end as'sale date',
pp.ls_table,
(pv.land_hstd_val + pv.land_non_hstd_val + pv.ag_market + pv.timber_market)as land_val,
cast(pp.[main_land_total_adj]as decimal (5,2)) as land_adj_total,
(pv.imprv_hstd_val + pv.imprv_non_hstd_val)as imprv_val,
case when [sale_date] >='01/01/2014'then [sale_price] else 0 end as'sale price',
pv.market
from property_val pv with (nolock)
inner join prop_supp_assoc psa with (nolock) on
pv.prop_id = psa.prop_id
and pv.prop_val_yr = psa.owner_tax_yr
and pv.sup_num = psa.sup_num
inner join property p with (nolock)on
pv.prop_id = p.prop_id
inner join owner o with (nolock) on
pv.prop_id = o.prop_id
and pv.prop_val_yr = o.owner_tax_yr
and pv.sup_num = o.sup_num
inner join account ac with (nolock) on
o.owner_id = ac.acct_id
inner join property_profile pp with (nolock) on
pv.prop_id = pp.prop_id
and pv.prop_val_yr = pp.prop_val_yr
left outer join imprv_detail as id1 with (nolock) on
pv.prop_id = id1.prop_id
and pv.prop_val_yr = id1.prop_val_yr
and pv.sup_num = id1.sup_num
left outer join
(select cop.prop_id,
convert(varchar(20), co.deed_dt, 101) as deed_date,
co.consideration as consideration, s.sl_dt as sale_date,
s.sl_price as sale_price, s.sl_type_cd as sale_type
from chg_of_owner_prop_assoc cop with (nolock)
inner join chg_of_owner co with (nolock) on
co.chg_of_owner_id = cop.chg_of_owner_id
inner join sale s with (nolock) on
co.chg_of_owner_id = s.chg_of_owner_id
where cop.seq_num = 0
)as c
on c.prop_id = pv.prop_id
basic results with some columns hidden-----
prop_id address street living_area total_area acres
x 322 SURBER ST 939 48 0
x 322 SURBER ST 939 288 0
x 322 SURBER ST 939 939 0
xy 318 SURBER STRE 1202 0 0
xy 318 SURBER STRE 1202 120 0
xy 318 SURBER STRE 1202 340 0
xy 318 SURBER STRE 1202 1052 0
if you need only additional sum and all currently returned rows then use SUM OVER function:
sum(id1.[calc_area] - pp.living_area) over (PARTITION BY pv.prop_id, pv.prop_val_yr) as [other_ area]
you can modify partitioning, for example:
sum(id1.[calc_area] - pp.living_area) over (PARTITION BY pv.prop_id, pv.prop_val_yr, pp.ls_table) as [other_ area]
but if you have unwanted row multiplication when you join table and you need aggregated values from this table, then use subquery in OUTER APPLY clause (and don't join this table in other way), for example:
SELECT ...
, id1.total_area
...
OUTER APPLY (
SELECT Sum(calc_area) as total_area
FROM imprv_detail
WHERE prop_id = pv.prop_id = id1.
and prop_val_yr = pv.prop_val_yr
and sup_num = pv.sup_num
) AS id1
then to calculate other_area use total_area - total_living_area

Max count SQL Server

I will explain my question with a practical example so that it is easier to visualize the issue. I have build this query:
Select
E.Tipo_Esp, F.Nome, F.Apelido,
count (Ac.id_acto) as total_consultas
from
Especialidade as E
right join
Funcionario as F on F.id_Esp = E.id_Esp
inner join
Acto as Ac on Ac.id_func = F.id_func
inner join
TipoActo as TA on TA.id_Tipo_acto = Ac.id_Tipo_acto
where
TA.Descricao_Acto = 'Consulta'
group by
E.Tipo_Esp, F.Nome, F.Apelido
order by
count(Ac.id_acto) DESC
to arrive to the following result:
Tipo_Esp Nome Apelido total_consultas
Ortopedia Maria Antonia 3
Ortopedia Luis Cruz 1
Cirurgia André Martins 2
Cirurgia Diogo Martins 1
However what I need to arrive is this:
Tipo_Esp Nome Apelido total_consultas
Ortopedia Maria Antonia 3
Cirurgia André Martins 2
meaning I only need the higher count for each "Tipo_Esp". I have tried to apply the max count function with the above query as a subquery but it did went well as expected. can someone help me with this issue please? thanks in advance
You could do this:
with orig as (
Select E.Tipo_Esp, F.Nome, F.Apelido, count (Ac.id_acto) as total_consultas from
Especialidade as E
right join Funcionario as F on F.id_Esp = E.id_Esp
inner join Acto as Ac on Ac.id_func = F.id_func
inner join TipoActo as TA on TA.id_Tipo_acto = Ac.id_Tipo_acto
WHERE TA.Descricao_Acto = 'Consulta'
GROUP BY E.Tipo_Esp, F.Nome, F.Apelido
ORDER BY count(Ac.id_acto) DESC
)
select o.*
from orig o
inner join (
select tipo_esp, max(total_consultas) as maxtotal
from orig
group by tipo_esp
) t on o.tipo_esp = t.tipo_esp and o.total_consultas = t.maxtotal

Crosstab/cross over query

Given data looks like
PLI_ID OWN_ID DCSF_ID SCH_NAME PREMIUM1 PREMIUM2 DESCRIPTION
901 2 1000 Dfe-School 1 86.40 7.20 Heads, Deps
902 2 1000 Dfe-School 2 403.30 8.40 Relief Bursar
903 2 1000 Dfe-School 3 327.00 8.40 £10.00
904 2 1000 Dfe-School 4 381.50 8.40 £11.00
905 2 1000 Dfe-School 5 152.60 8.40 Teaching staff
Expected data to look like
School £10.00 £11.00 Heads, Deps Relief Bursar Teaching staff Total
Dfe-School 1
Dfe-School 2
Dfe-School 3
Dfe-School 4
Total [Pre-Total]
I am not sure whether to write a Cross Tab or Cross Over query, as suggested. Let me know, if need more explanation.
My query uses around 6 tables and it looks like this:
SELECT PolicyLine.PLI_POS_Id, Policy.POL_OWN_Id, Policy.POL_DCSF, School.SCH_Name, PolicyLine.PLI_Premium, CoverPremium.CPR_Premium, StaffCategory.SCA_Description FROM
School
INNER JOIN Policy ON School.SCH_OWN_Id = Policy.POL_OWN_Id AND School.SCH_DCSF = Policy.POL_DCSF
INNER JOIN PolicyLine ON Policy.POL_Id = PolicyLine.PLI_POL_Id
INNER JOIN CoverOption ON PolicyLine.PLI_COP_Id = CoverOption.COP_Id
INNER JOIN CoverPremium ON CoverOption.COP_Id = CoverPremium.CPR_COP_Id AND Policy.POL_OWN_Id = CoverPremium.CPR_OWN_Id
RIGHT OUTER JOIN StaffCategory ON CoverOption.COP_SCA_Id = StaffCategory.SCA_
Based on your existing query you would use something like this:
SELECT School.SCH_Name school,
[£10.00], [£11.00],
[Heads, Deps], [Relief Bursar], [Teaching staff]
FROM
(
SELECT PolicyLine.PLI_POS_Id,
Policy.POL_OWN_Id,
Policy.POL_DCSF,
School.SCH_Name,
PolicyLine.PLI_Premium,
CoverPremium.CPR_Premium,
StaffCategory.SCA_Description
FROM School
INNER JOIN Policy
ON School.SCH_OWN_Id = Policy.POL_OWN_Id
AND School.SCH_DCSF = Policy.POL_DCSF
INNER JOIN PolicyLine
ON Policy.POL_Id = PolicyLine.PLI_POL_Id
INNER JOIN CoverOption
ON PolicyLine.PLI_COP_Id = CoverOption.COP_Id
INNER JOIN CoverPremium
ON CoverOption.COP_Id = CoverPremium.CPR_COP_Id
AND Policy.POL_OWN_Id = CoverPremium.CPR_OWN_Id
RIGHT OUTER JOIN StaffCategory
ON CoverOption.COP_SCA_Id = StaffCategory.SCA_
) x
PIVOT
(
sum(PLI_Premium)
for SCA_Description in([£10.00], [£11.00],
[Heads, Deps], [Relief Bursar], [Teaching staff])
) p
See SQL Fiddle with Demo
You probably want a PIVOT query, but from your example it's hard to tell what that should look like.
SELECT *
FROM yourtable
PIVOT
(SUM(Premium) FOR sch_name in ([£10.00],[£11.00],[Heads, Deps],[Relief Bursar],[Teaching staff]))

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;