Select student do most of the project in least amount of time - sql

I have 2 tables, STUDENT(stu_id, name) and PROJECT(project_id, name), linked together by TASK(stu_id, project_id, duration), how can I find student with the number of projects is the largest while the duration of all that projects is the least? I've already tried this, but it's definitely wrong, since it find MAX COUNT PROJECT then join with MIN SUM DURATION, not MAX COUNT PROJECT AND MIN SUM DURATION
--WRONG
SELECT S.stu_id, S.stu_name
FROM STUDENT AS S
LEFT JOIN TASK AS T
ON S.stu_id = T.stu_id
GROUP BY S.stu_id, S.stu_name
HAVING COUNT(T.project_id) >= ALL(
SELECT COUNT(T1.project_id)
FROM TASK AS T1
GROUP BY T1.stu_id
)
AND SUM(T.duration) <= ALL(
SELECT SUM(T2.duration)
FROM TASK AS T2
GROUP BY T2.stu_id
)

how can I find student with the number of projects is the largest while the duration of all that projects is the least?
This sounds like aggregation and limiting:
select top (1) stu_id, count(*) as num_projects, sum(duration) as total_duration
from task
group by stu_id
order by count(*) desc, sum(duration) asc;

Related

How to COUNT (*) WHERE column1 is >= The maximum value for specific value in column2?

title
duration
programme a
1000
programme b
1500
I have a table like this, and I want to count all rows where the duration is at least 90% of the MAXIMUM duration of the programme in said row. How can I do this?
For context, each row is a play event, and duration is how long in seconds the play event lasted
None of the other answers take into account, that the MAX should be calculated per title as per the at least 90% of the MAXIMUM duration of the programme in said row part of the original post.
SELECT
COUNT(*)
FROM
table T
INNER JOIN (
SELECT title, MAX(duration) AS max_duration FROM table GROUP BY title)
) X
ON T.title= X.title
WHERE
T.duration >= X.max_duration * 0.9
I am assuming, that the title is unique (per programme) in the above, if not, replace that column with the correct identifier.
This might work:
SELECT COUNT(*) FROM your_table, (SELECT MAX(duration) AS m FROM your_table) AS sq
WHERE duration/m >= 0.9
WITH max_duration_by_title AS (SELECT title, MAX(duration) AS max_duration FROM your_table GROUP BY title)
SELECT base_table.title
, COUNT(1) AS total_plays
, COUNT (CASE WHEN base_table.duration >= 0.9 * max_duration.max_duration THEN 1 END) AS total_plays_longer_than_threshold
FROM your_table base_table
INNER JOIN max_duration_by_title
ON base_table.title = max_duration_by_title.title
GROUP BY base_table.title

Group By 2 Columns and Find Percentage of Group In SQL

I have a Game table with two columns TeamZeroScore and TeamOneScore. I would like to calculate the % of games that end with each score variance. The max score one team can have is 5.
I have got the following code which selects each team score with an additional 2 columns to have the max and min of these two values in order. I did this because I thought the next step is to group by these two columns
SELECT TOP (100000) [TeamOneScore],[TeamZeroScore],
(SELECT Max(v)
FROM (VALUES ([TeamOneScore]), ([TeamZeroScore])) AS value(v)) as [MaxScore],
(SELECT Min(v)
FROM (VALUES ([TeamOneScore]), ([TeamZeroScore])) AS value(v)) as [MinScore]
FROM [Database].[dbo].[Game]
Below is the sample data I have for the code above.
How do I produce something similar to this? I think I need to Group By MaxScore, MinScore and then use Count on each group to calculate the percentage based on the total.
Select
Count(*) as "number",
(100 * count(*)) / t
As "percentage",
TeamOneScore as score,
TeamTwoScore as score
From
( Select
TeamOneScore,TeamTwoScore
From tablename
Where TeamOneScore <= TeamTwoScore
Union all
Select
TeamTwoScore,TeamOneScore
from tablename
Where TeamOneScore > TeamTwoScore
) a,
(Select count(*) as t
From tablename) b
Group by
TeamOneScore,
TeamTwoScore
Order by
TeamOneScore,
TeamTwoScore;

How to create an additional column with the percentages related to a count distinct statement

I'm trying to query each distinct medical speciality (e.g. oncologist, pediatrician, etc.) in a table and then count the number of times a claim (claim_id) is linked to it, which I've done using this:
select distinct specialization, count(distinct claim_id) AS Claim_Totals
from table1
group by specialization
order by Claim_Totals DESC
However, I also want to include an additional column which lists the % that each speciality makes up in the table (based on the number of claim_id related to it). So for instance, if there were 100 total claims and "cardiologist" had 25 claim_id records related to it, "oncologist" had 15, "general surgeon" had 10, and so forth, I want the output to look like this:
specialization | Claims_Totals | PERCENTAGE
___________________________________________
cardiologist 25 25%
oncologist 15 15%
general surgeon 10 10%
Could do this? I'm not familiar with Barbaros's syntax. If that works its more concise and better.
select specialization, count(distinct claim_id) AS Claim_Totals, count(distinct claim_id)/total_claims
from table1
INNER JOIN ( SELECT COUNT(DISTINCT claim_id)*1.0000 total_claims AS total_claims
FROM table1 ) TMP
ON 1 = 1
group by specialization
order by Claim_Totals DESC
select specialization,
count(distinct claim_id) AS claim_by_spec,
count(distinct claim_id)/
( SELECT COUNT(DISTINCT claim_id)*1.0000
FROM table1 ) AS percentage_calc
from table1
group by specialization
order by Claim_Totals DESC
You can use sum(count(distinct)) over() to get the overall claims and use it in the denominator to get the percentage.
select specialization
,count(distinct claim_id) AS Claim_Totals
,round(100*count(distinct claim_id)/sum(count(distinct claim_id)) over(),3) as percentage
from table1
group by specialization
You can use
,concat_ws('',count(distinct claim_id),'%') as percentage
or
,concat(count(distinct claim_id),'%') as percentage
as added to the select list's tail
Btw, distinct before specialization in the select list is redundant, since already included in the group by list.
Because you are using count(distinct), window functions are less useful. You can try:
select t1.specialization,
count(distinct t1.claim_id) AS Claim_Totals,
count(distinct t1.claim_id) / tt1.num_claims
from table1 t1 cross join
(select count(distinct claim_id) as num_claims
from table1
) tt1
group by t1.specialization
order by Claim_Totals DESC

sql - Find the ID of the most booked flight

In the booking table I'm using, the fields are FlightNo, CustomerNo, DateOfFlight, DateBooked
I'm trying to find the flight number of the most booked flight. I have 5 bookings for flight101 and 2 for flight105 but the below code is returning flight105 as the result.
SELECT distinct(flightNo)
FROM booking
WHERE flightNo IN
(SELECT max(flightNo) AS maximum FROM booking);
I think you could use a group by to fix
select flightNo, count(*) from booking group by flightNo
Here you are grouping the results to flightNo and counting all the records given this flightNo. If you want to only display 1 record the most booked flight order it by count(*) desc and limit the results to 1.
select flightNo, count(*) from booking group by flightNo order by count(*) desc limit 1

How to calculate average users visits per day

I have a requests table which include request data for my my page requests. I have field including Id, UserAgent, Ip, EventDateUtc, etc. How to write SQL which give me average requests per day.
You can get a count grouped by UserAgent,EventDateUtc and then do a AVG on top of it.
SELECT AVG(reccount) avg_count,EventDateUtc
FROM
(
SELECT COUNT(*) reccount,UserAgent, CONVERT(DATE,EventDateUtc) EventDateUtc
FROM PageVisit
GROUP BY CONVERT(DATE,EventDateUtc),UserAgent
)T
GROUP BY EventDateUtc
If you want a total average for all days, don't do a GROUP BY in the outer query.
SELECT AVG(reccount) avg_count
FROM
(
SELECT COUNT(*) reccount,UserAgent, CONVERT(DATE,EventDateUtc) EventDateUtc
FROM PageVisit
GROUP BY CONVERT(DATE,EventDateUtc),UserAgent
)T
The inner select counts visits / day, the outer the average:
select avg(cnt)
from (select count(*) as cnt
from tablename
group by EventDateUtc)