Get all items with min values SQL Server - sql

Here's what the table is like:
----------------------------------
EmployeeId Tasks_Count
1 1
2 1
3 2
4 1
5 3
I need a query to get all employees with min tasks count. Result should be like this:
---------------
EmployeeId
1
2
4
The problem is that i using a subquery to count tasks. Here's my code
SELECT *
FROM (SELECT EmployeeId,
COUNT(*) AS Tasks_count
FROM Tasks
INNER JOIN Status ON Tasks.StatusId=Status.Id
WHERE Status.Name != 'Closed'
GROUP BY EmployeeId
ORDER BY Tasks_count DESC) AS Employee_not_closed
WHERE Tasks_count IN (SELECT MIN(Tasks_count)
FROM Employee_not_closed)

Use FETCH FIRST WITH TIES:
select EmployeeId
from tablename
order by Tasks_Count
fetch first 1 row with ties

You can try below -
select * from tablename
where Tasks_Count in (select min(Tasks_Count) from tablename)

It can also be done using RANK() function like following.
;with cte as
(
select Employeeid, rank() over( order by Tasks_Count) rn
from #table
)
select * from cte where rn=1

You Can use the below code i have tested the code and its working fine.
select EmployeeId from StackOverFlow_3 where Tasks_Count in(select min(Tasks_Count) from StackOverFlow_3)

You can use a join on subquery
select m.EmployeeId
from my_table m
inner join
(
select min(task_count) min_task
from my_table
) t on t.min_task = m.task_count

Related

Group by column and get max and min id on sql

I got a table with theses Column :
ID_REAL,DATE_REAL,NAME_REAL
I want to make a query to get result like this with a group by on the name
NAME | MAX(DATE_REAL) | ID_REAL of the MAX(DATE_REAL) | MIN(DATE_REAL) | ID_REAL of the MIN(DATE_REAL)
I dont know how to make it for the moment I have
select NAME_REAL,max(DATE_REAL),ID_REAL from MYREALTABLE group by NAME_REAL,ID_REAL
select NAME_REAL,min(DATE_REAL),ID_REAL from MYREALTABLE group by NAME_REAL,ID_REAL
But is not whats I need, and also I need only 1 query
Thanks you
I think the following should work by finding the records which have the minimum and maximum dates per name and joining those two queries.
select
mn.NAME_REAL,
MIN_DATE_REAL,
ID_REAL_OF_MIN_DATE_REAL,
MAX_DATE_REAL,
ID_REAL_OF_MAXDATE_REAL
from
(
select NAME_REAL,
DATE_REAL as MIN_DATE_REAL,
ID_REAL as ID_REAL_OF_MIN_DATE_REAL,
from (
select
NAME_REAL,
ID_REAL,
DATE_REAL,
row_number() over (partition by NAME_REAL order by DATE_REAL asc) as date_order_asc
from MYREALTABLE
)
where date_order_asc = 1
) mn
inner join
(
select NAME_REAL,
DATE_REAL as MAX_DATE_REAL,
ID_REAL as ID_REAL_OF_MAX_DATE_REAL,
from (
select
NAME_REAL,
ID_REAL,
DATE_REAL,
row_number() over (partition by NAME_REAL order by DATE_REAL desc) as date_order_desc
from MYREALTABLE
)
where date_order_desc = 1
) mx
on mn.NAME_REAL = mx.NAME_REAL
You can join the two results into a single query result as follows
select o.NAME_REAL,o.max,o.id_real,t.min,o.id_real from (
select NAME_REAL,max(DATE_REAL) as max,ID_REAL, from MYREALTABLE group by NAME_REAL,ID_REAL)
as o inner join
(select NAME_REAL,min(DATE_REAL),ID_REAL from MYREALTABLE group by NAME_REAL,ID_REAL
) as t on o.NAME_REAL=t.NAME_REAL
Try the below -
select NAME_REAL,ID_REAL,max(DATE_REAL) as max_date, min(DATE_REAL) as min_date
from MYREALTABLE
group by NAME_REAL,ID_REAL

function that allows grouping of rows

I'm using SQL Server Management Studio 2012. I have a similar looking output from a query shown below. I want to eliminate someone from the query who has 2 contracts.
Select
Row_Number() over (partition by ID ORDER BY ContractypeDescription DESC) as [Row_Number],
Name,
ContractDescription,
Role
From table
Output
Row_Number ID Name Contract Description Role
1 1234 Mike FullTime Admin
2 1234 Mike Temp Manager
1 5678 Dave FullTime Admin
1 9785 Liz FullTime Admin
What I would like to see
Row_Number ID Name Contract Description Role
1 5678 Dave FullTime Admin
1 9785 Liz FullTime Admin
Is there a function rather than Row_Number that allows you to group rows together so I can then use something like 'where Row_Number not like 1 and 2'?
You can use HAVING as
SELECT ID,
MAX(Name) Name,
MAX(ContractDescription) ContractDescription,
MAX(Role) Role
FROM t
GROUP BY ID
HAVING COUNT(*) = 1;
Demo
Try this:
select * from (
Select
Count(*) over (partition by ID ) as [Row_Number],
Name,
ContractDescription,
Role
From table
)t where [Row_Number] = 1
You can check this option-
SELECT *
FROM table
WHERE ID IN
(
SELECT ID
FROM table
GROUP BY ID
HAVING COUNT(*) = 1
)
You can use a CTE to get all the ids of people who got only one contract and then just join the result of the CTE with your table.
;with cte as (
select
id
,COUNT(id) as no
from #tbl
group by id
having COUNT(id) = 1
)
select
t.id
,t.name
,t.ContractDescription
,t.role
from #tbl t
inner join cte
on t.id = cte.id
Basically you need those record who have exactly one contract.
Just extend your script, (My script is not tested)
;with CTE as
(
Select
Row_Number() over (partition by ID ORDER BY ContractypeDescription DESC) as [Row_Number],
Name,
ContractDescription,
Role
From table
)
select * from CTE c where [Row_Number]=1
and not exists(select 1 from CTE c1 where c.id=c1.id and c1.[Row_Number]>1 )
Is there a function rather than Row_Number that allows you to group
rows together so I can then use something like 'where Row_Number not
like 1 and 2'?
You can use a windowed COUNT(). The key is the OVER() clause.
;WITH WindowedCount AS
(
SELECT
T.*,
WindowCount = COUNT(1) OVER (PARTITION BY T.ID)
FROM
YourTable AS T
)
DELETE W FROM
WindowedCount AS W
WHERE
W.WindowCount > 1
The COUNT() will count the amount of rows for each different ID, so if the same ID appears in 2 or more rows, those rows will be deleted.

MSSQL How Can I Get the latest Amount

How can I get the Latest amount, I already had some queries but instead it shows two records ,Im expecting to show only the the '7370' current amount
you can use correlated subquery
select * from tablename a where lasttime in (select max(lasttime) from tablename b where a.id=b.id)
OR you can use row_number()
select * from
(
select *,row_number() over(partition by id order by lasttime desc) as rn from tablename
)A where rn=1
Just add Top 1 before your fields.
Select TOP 1 fields from table
SELECT TOP 1 currentBalance FROM DBO.tbl_billing ORDER BY [date]

Using DISTINCT and TOP in the same query

I want to use DISTINCT and TOP in the same query. I tried
SELECT DISTINCT TOP 10 * FROM TableA
but I still have a duplicate personID, so I tought to do:
SELECT DISTINCT (personID) TOP 10 * FROM TableA
But here the syntax is wrong. How do I do it correctly?
You're using a SELECT * which is pulling in all records. If you want to use a true DISTINCT only list out the column you want to receive distinct values of. If you have multiple columns then all those columns combined make up one distinct record.
SELECT distinct TOP 10 personID
FROM TableA
Note that without an ORDER BY this will return the first 10 records in no particular order. The results could be different each time you run the query.
You seem to want 10 random records for different persons. Try this:
select t.*
from (select t.*,
row_number() over (partition by personid order by (select NULL)) as seqnum
from t
) t
where seqnum = 1
In general, though, when using top you should also be using an order by to specify what you mean by "top".
It works simply if you use query like this:
SELECT DISTINCT TOP 2 name FROM [ATTENDANCE] ;
In the above query, name is the column_name and [ATTENDANCE] is the table_name.
You can also use WHERE with this to make filtering conditions.
select distinct personid from tablea sample 10
This works in teradata
Maybe you can do like this:
SELECT TOP 10 t.* FROM (SELECT distinct personID FROM TableA) t
Few options:
1:
SELECT TOP 10 personID
FROM (SELECT distinct personID FROM TableA)
2:
;with cte as
(SELECT distinct personID FROM TableA)
SELECT top 10 personID FROM cte
3:
;with cte as
(SELECT personID,row_count=row_number() over (partition by personID order by personID)
FROM TableA
) SELECT top 10 personID FROM cte where row_count=1
I see this is an old question, but I can suggest a more elegant solution:
SELECT personDetails.*
FROM
(
SELECT TOP (10)
personID
personID
FROM TableA
GROUP BY personID --> use this instead of distinct
) AS distinctIds
OUTER APPLY
(
SELECT TOP (1) * --> fetch only one result matching personID
FROM TableA
WHERE TableA.personId = distinctIds.personID
) AS personDetails
You can use GROUP BY instead of DISTINCT, and you can use OUTER APPLY with TOP(1) to fetch only one matching result.
The Matt Busche answer is correct based on the post title.
But if, as it seems from your code examples, your problem is to have all the record fields from the distinct top 10 personID, you can use that as a subquery:
SELECT TableA.*
FROM TableA
INNER JOIN (SELECT DISTINCT TOP 10 personID FROM TableA) AS B
ON TableA.ID = B.ID
SELECT DISTINCT ta.personid FROM (SELECT TOP 10 * FROM TableA) ta
ta is object of subquery and using ta object we can distinct the values
i fixed it i did
select distinct personid from (SELECT TOP 10 * FROM TableA)
If the goal is to select the top 1 record of every personID, then use
select * from TableA group by personid
Since you are doing a "group by", it will return every column, but will ignore (not display) any additional rows with the same personId

how to calculate count in sql?

I have the following table:
memberid
2
2
3
4
3
...and I want the following result:
memberid count
2 2
3 1 ---Edit by gbn: do you mean 2?
4 1
I was attempting to use:
SELECT MemberID,
COUNT(MemberID)
FROM YourTable
GROUP BY MemberID
...but now I want find which record which has maximum count. IE:
memberid count
2 2
SELECT memberid, COUNT(*) FROM TheTable GROUP BY memberid
Although, it won't work for your desired output because you have "memberid = 3" twice.
Edit: After late update to question...
SELECT TOP 1 WITH TIES --WITH TIES will pick up "joint top".
memberid, COUNT(*)
FROM
TheTable
GROUP BY
memberid
ORDER BY
COUNT(*) DESC
SELECT MemberID, COUNT(MemberID) FROM YourTable GROUP BY MemberID
What if there is a tie (or more) for the max? Do you want to display one or all?
This is how I would do this
SELECT memberid, COUNT(1)
FROM members
GROUP BY memberid
HAVING COUNT(1) = (
SELECT MAX(result.mem_count)
FROM (
SELECT memberid, COUNT(1) as mem_count
FROM members
GROUP BY memberid
) as result
)
I would love to see a more efficient approach though.
Do it like this:
SELECT memberid, COUNT(memberid) AS [count] FROM [Table] GROUP BY memberid
This should do the trick with no subselects required:
select top 1 memberid, COUNT(*) as counted
from members
group by memberid
order by counted desc
Can be done quite easy:
SELECT TOP 1 MemberId, COUNT(*) FROM YourTable GROUP BY MemberId ORDER By 2 DESC
I believe the original poster requested 2 result sets.
The only way I know of to get this (in SQL Server) is to dump the original records into a temp table and then do a SELECT and MAX on that. I do welcome an answer that requires less code!
-- Select records into a temp table
SELECT
Table1.MemberId
,CNT = COUNT(*)
INTO #Temp
FROM YourTable AS Table1
GROUP BY Table1.MemberId
ORDER BY Table1.MemberId
-- Get original records
SELECT * FROM #Temp
-- Get max. count record(s)
SELECT
Table1.MemberId
,Table1.CNT
FROM #Temp AS Table1
INNER JOIN (
SELECT CNT = MAX(CNT)
FROM #Temp
) AS Table2 ON Table2.CNT = Table1.CNT
-- Cleanup
DROP TABLE #Temp
How about this query:
SELECT TOP 1 MemberID,
COUNT(MemberID)
FROM YourTable
GROUP BY MemberID
ORDER by count(MemberID) desc
SELECT count(column_name)
FROM your_table;
You need to use a subselect:
SELECT MemberID, MAX(Count) FROM
(SELECT MemberID, COUNT(MemberID) Count FROM YourTable GROUP BY MemberID)
GROUP BY MemberID
The second group by is needed to return both, the count and the MemberID.