This question already has answers here:
In SQL, how to select the top 2 rows for each group
(8 answers)
Closed 3 years ago.
I am trying to find the top 3 sick leavers per Site in my employee table. Im attempting to write a query to find the top sick leaver per site first.
Here is what I have but I can't seem to get it right
Here's what I have
select Site.SiteName,
[FullName] where MAX([SickLeaveTaken])
from Employee
left join Site
on(Employee.SiteID=Site.SiteID)
GROUP BY Site.SiteName;
GO
You can get top 3 employees with max sick leave by using RANK function in SQL
select top 3 EmployeeID,SickLeaveTaken,s.SiteName,rn from
(select e.EmployeeID,SickLeaveTaken,e.SiteID ,RANK() over(order by [SickLeaveTaken]
desc ) as rn
from #Employee e )e
left join #Site s on e.SiteID=s.SiteID
order by rn desc
Assuming that the table Employee contains the column SickLeaveTaken (although this is not normal) you need to sort descending the results and get TOP 3:
select TOP(3) WITH TIES
s.SiteName,
e.FullName,
MAX(e.SickLeaveTaken) maxleave
from Site s inner join Employee e
on e.SiteID = s.SiteID
GROUP BY s.SiteName, e.FullName
ORDER BY MAX(e.SickLeaveTaken) DESC;
Related
I have two tables FileMaster and VendorMaster.
In VendorMaster i have vendor id and other stuff. in FileMaster i have file related data where 'Vendorid' is foreign key in FileMaster. Now I want to fetch top 10 data from FileMaster for Each 'Vendor' (One record for one vendor).
I have tried below query, but it returns me 10 records with duplicate vendorID
select top 10 * from FileMaster where VendorId in (select top 10 VendorId from VendorMaster)
You can use ROW_NUMBER. I assumed FileID column for the identity of File Master. By the way, you don't need any subquery
SELECT TOP 10 * FROM (
select *,
ROW_NUMBER() OVER(PARTITION BY VendorID ORDER BY FileID) AS RN
FROM FileMaster ) AS T
WHERE RN = 1
ORDER BY FileID
Here you can use simple way instead of subquery
Or Anther way you can use CTE click this Link
SELECT DISTINCT FM.*
FROM FileMaster FM WITH(NOLOCK)
INNER JOIN [dbo].[VendorMaster] VM WITH(NOLOCK)
ON FM.VendorId = VM.VendorId
ORDER BY FM.VendorId ASC
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY
For more details OFFSET related check this Link
I have an exercise in SQL Server: I have two tables Country and Events.
The Events table holds the event details including the city where an event happens. The table Events has a foreign key CountryID (CountryID is the primary key in table Country).
I need to create a temporary table showing the most eventful country for each year.
Any help would be appreciated
Thanks
You weren't far off with your attempt, but you need to use a CTE to aggregate your data first. I've assumed that the final order of your data is important, so I used a second CTE, rather than a TOP 1 WITH TIES tio get the final result:
WITH CTE AS(
SELECT YEAR(e.EventDate) AS YearOfEvent,
c.CountryName,
COUNT(e.CountryID) AS NumberOfEvents
FROM [dbo].[tblEvent] AS e
INNER JOIN tblCountry AS c ON e.CountryID = c.CountryID
GROUP BY e.CountryId,
c.CountryName,
YEAR(e.EventDate)),
RNs AS(
SELECT YearOfEvent,
CountryName,
NumberOfEvents,
ROW_NUMBER() OVER (PARTITION BY YearOfEvent ORDER BY CTE.NumberOfEvents DESC) AS RN
FROM CTE)
SELECT YearOfEvent,
CountryName,
NumberOfEvents
FROM RNs
WHERE RN = 1
ORDER BY RNs.YearOfEvent ASC;
I'm trying to find out the most dosed patients in a database. The sum of the doses has to be calculated and then I have to dynamically list out the patients who have been dosed that much. The query has to be dynamic, and there can be more than 5 patients listed - For example, the 5 most doses are 7,6,5,4,3 doses, but 3 people have gotten 5 doses, so I'd have to list out 7 people in total (the patients getting 7,6,5,5,5,4,3 doses). I'm having issues because you cannot refer to a named column in a where clause and I have no idea how to fix this.
The query goes like this:
SELECT
info.NAME, SUM(therapy.DOSE) AS total
FROM
dbo.PATIENT_INFORMATION_TBL info
JOIN
dbo.PATIENT_THERAPY_TBL therapy ON info.HOSPITAL_NUMBER = therapy.HOSPITAL_NUMBER
LEFT JOIN
dbo.FORMULARY_CLINICAL clinical ON clinical.ITEMID = therapy.ITEMID
WHERE
total IN (SELECT DISTINCT TOP 5 SUM(t.DOSE) AS 'DOSES'
FROM dbo.PATIENT_INFORMATION_TBL i
JOIN dbo.PATIENT_THERAPY_TBL t ON i.HOSPITAL_NUMBER = t.HOSPITAL_NUMBER
LEFT JOIN dbo.FORMULARY_CLINICAL c ON c.ITEMID = t.ITEMID
GROUP BY NAME
ORDER BY 'DOSES' DESC)
GROUP BY
info.NAME
ORDER BY
total DESC
The database looks like this:
The main question is: how can I use a where/having clause where I need to compare a calculated column to a list of dynamically calculated values?
I'm using Microsoft's SQL Server 2012. The DISTINCT in the subquery is needed so that only the top 5 dosages appear (e.g. without DISTINCT I get 7,6,5,4,3 with DISTINCT I get 7,6,6,5,4 and my goal is the first one).
Most DBMSes support Standard SQL Analytical Functions like DENSE_RANK:
with cte as
(
SELECT info.NAME, SUM(therapy.DOSE) as total,
DENSE_RANK() OVER (ORDER BY SUM(therapy.DOSE) DESC) AS dr
FROM dbo.PATIENT_INFORMATION_TBL info
JOIN dbo.PATIENT_THERAPY_TBL therapy ON info.HOSPITAL_NUMBER=therapy.HOSPITAL_NUMBER
LEFT JOIN dbo.FORMULARY_CLINICAL clinical ON clinical.ITEMID=therapy.ITEMID
GROUP BY info.NAME
)
select *
from cte
where dr <= 5 -- only the five highest doses
ORDER BY total desc
Btw, you probably don't need the LEFT JOIN as you're not selecting any column from dbo.FORMULARY_CLINICAL
This question already has answers here:
GROUP BY / aggregate function confusion in SQL
(5 answers)
Closed 5 years ago.
I have SQL code like this :
SELECT
TB_DataProperti.*,
TBL_Rating.ISNULL(AVG(Rating), 0) AverageRating
FROM
TB_DataProperti
INNER JOIN
TBL_Rating ON TB_DataProperti.Kode_Properti = TBL_Rating.Kode_Properti
GROUP BY
TB_DataProperti.JudulListing
ORDER BY
AverageRating DESC
I get this error:
Msg 8120, Level 16, State 1, Line 3
Column 'TB_DataProperti.Kode_Properti' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I just want to select all data columns using *, because I have many columns
Problem is You are trying to use aggregate function of one table and group by on another table.The rule is if you are using aggregate function with another column then that column should use in group by.Still try this I hope this is useful.
SELECT
TB_DataProperti.*,
ISNULL(AVG(TBL_Rating.Rating), 0) over (partition by TBL_Rating.Kode_Properti) as AverageRating
FROM
TB_DataProperti
INNER JOIN
TBL_Rating ON TB_DataProperti.Kode_Properti = TBL_Rating.Kode_Properti
ORDER BY
AverageRating DESC
SELECT top 3 a.[CustID],a.[CustName],a.[ContactNo],a.[Address],[EmailID] ,
(select count(1) FROM tblCustomer x) as [RecordCount]
FROM tblCustomer a
where a.[CustID] NOT IN (
SELECT TOP 6 m.[CustID]
FROM tblCustomer m
Order by m.[CreatedOn] desc)
order by a.[CreatedOn] desc
I m trying to Get top 3 Result from above Query but I m getting a lot more than that:
Can someone Recorrect above query ..
TOP in Ms Access includes not just the required number, but all matched results. In this case you have chosen date, so if there are several matched dates, they will all be returned. If you need just three records, order by a unique field in addition to the required sort order. For example
... order by a.[CreatedOn] desc, custid