Max count SQL Server - sql

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

Related

Is there any effect on Result due to column ordering in Group by clause in SQL server

If i have 20 columns and want to get result based on group by clause. Is there any effect on result if I change the order of columns in SQL query.
My example is as follows :
Select
R.ClientId
,R.FirmName
,R.StrategyID
,R.SecurityType
,SUM(R.QtySent)
,SUM(R.ExecutedQty) AS ExecutedQty
,SUM(R.CrossedExecutedQty) AS CrossedExecutedQty
FROM ClientDetail m inner join ClientMaster c on
m.clordid = c.masterorderId
and m.msg_id = 43
and c.msg_id in (10,11,12,40)--Msg_Id 40 for manual trade
inner join #ResultsDaily R on c.clordid = R.clordid
GROUP BY R.TethysClientId
,R.FirmName
,R.StrategyID
,R.SecurityType
--Query 1
SELECT R.ClientId --A
,R.FirmName --B
,R.StrategyID --C
,R.SecurityType --D
,SUM(R.QtySent)
,SUM(R.ExecutedQty) AS ExecutedQty
,SUM(R.CrossedExecutedQty) AS CrossedExecutedQty
FROM ClientDetail m
JOIN ClientMaster c
ON m.clordid = c.masterorderId
AND m.msg_id = 43
AND c.msg_id in (10,11,12,40)
JOIN #ResultsDaily R on c.clordid = R.clordid
GROUP BY R.TethysClientId --1
,R.FirmName --2
,R.StrategyID --3
,R.SecurityType --4
In the above Query, 1,2,3 and 4 can be of any order. same time A,B,C and D can be also be in any order.
No column should be missed , thats all.
Parden, if i misinterpreted the Question.

Merge results to one column

I have the following query:
SELECT a.User1 as Employee
, isnull(sum(distinct b.Page_Count),0) AS Yesterday
, isnull(sum(distinct c.Page_Count),0) AS Today
, isnull(sum(distinct d.Page_Count),0) AS Week
, e.Material_Location as '(Yesterday)'
, f.Material_Location as '(Today)'
From TaskUser AS a
LEFT JOIN PaperMaterial AS b
ON b.Assigned_To = a.User1
AND b.Date_Assigned between ('06/09/2014') AND ('06/13/2014')
LEFT JOIN PaperMaterial AS c
ON c.Assigned_To = a.User1
AND c.Date_Assigned between ('06/13/2014') AND ('06/14/2014')
LEFT JOIN PaperMaterial AS d
ON d.Assigned_To = a.User1
AND d.Date_Assigned between ('06/09/2014') AND ('06/14/2014')
LEFT JOIN PaperMaterial AS e
ON e.Assigned_To = a.User1
AND e.Date_Assigned between ('06/12/2014') AND ('06/13/2014')
LEFT JOIN PaperMaterial AS f
ON f.Assigned_To = a.User1
AND f.Date_Assigned between ('06/13/2014') AND ('06/14/2014')
GROUP BY a.User1, e.Material_Location, f.Material_Location
Order By a.User1, e.Material_Location, f.Material_Location
If multiple records were input for the same user on the same day, I am getting unique rows for the same person. I only want one row per user with the e and f results merged to the same column.
Ie: Current Output =
Amy 0 640 640 NoTask Task
Amy 0 640 640 Task2 Task
Amy 0 640 640 Task3 Task4
Amy 0 640 640 Task1 NoTask
Requested output:
Amy 0 640 640 (NoTask, Task1, Task2, Task3) (NoTask, Task, Task4)
Here's a greatly over-simplified example of using stuff combined with a correlated subquery:
SQL Fiddle
I used your output as a table, more or less:
select
name,
stuff(
(
select cast(',' as varchar(max)) + mt.one
from MyTable mt
WHERE mt.name = t1.name
order by mt.name
for xml path('')
), 1, 1, '')
from mytable t1
group by name
We're using stuff to concatenate each value for the column I creatively named ONE for each NAME. The correlated subquery allows us to relate each row coming out of that to the corresponding row coming out of the main query.

Maximum value from column while rows have different fields

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'

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;

Count Unique Results in T-SQL

My query is:
SELECT DISTINCT IncidentStatus.IncidentStatusName, Incident.IncidentID AS Bob
FROM Incident
INNER JOIN IncidentMember
ON Incident.IncidentID = IncidentMember.IncidentId
INNER JOIN IncidentStatus
ON Incident.IncidentStatusID = IncidentStatus.IncidentStatusID
WHERE (IncidentMember.MemberId = 6)
And the result is:
IncidentStatusName Bob
---------------------------
Closed 9267
In Progress 9251
In Progress 9289
New 7893
Resolved 7750
Required Result is:
IncidentStatusName Bob
---------------------------
Closed 1
In Progress 2
New 1
Resolved 1
Help Requested.
SELECT IncidentStatus.IncidentStatusName, COUNT(Incident.IncidentID) AS Bob
FROM Incident
INNER JOIN IncidentMember ON Incident.IncidentID = IncidentMember.IncidentId
INNER JOIN IncidentStatus ON Incident.IncidentStatusID = IncidentStatus.IncidentStatusID
WHERE (IncidentMember.MemberId = 6)
GROUP BY IncidentStatus.IncidentStatusName
Or maybe you need COUNT(DISTINCT Incident.IncidentID) (depends on your table structure)
take your PK field, Incident.IncidentID, out of the select distinct clause