SQL Group by & Max - sql

I have a following data in a table:
id name alarmId alarmUnit alarmLevel
1 test voltage psu warning
2 test voltage psu ceasing
3 test voltage psu warning
4 test temp rcc warning
5 test temp rcc ceasing
I'd like to show only the most recent information about every colums group (alarmId,alarmUnit), so the result should look like this:
3 test voltage psu warning
5 test temp rcc ceasing
I've tried so far:
SELECT MAX(id) as id,name,alarmId,alarmUnit,alarmLevel GROUP BY alarmId,alarmUnit;
Selected IDs seem to be fine but selected rows aren't corresponding to them. Could you help me?

In Oracle, SQL Server 2005+ and PostgreSQL 8.4:
SELECT *
FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY alarmId, alarmUnit ORDER BY id DESC) AS rn
FROM mytable
) q
WHERE rn = 1
In MySQL:
SELECT mi.*
FROM (
SELECT alarmId, alarmUnit, MAX(id) AS mid
FROM mytable
GROUP BY
alarmId, alarmUnit
) mo
JOIN mytable mi
ON mi.id = mo.mid
In PostgreSQL 8.3 and below:
SELECT DISTINCT ON (alarmId, alarmUnit) *
FROM mytable
ORDER BY
alarmId, alarmUnit, id DESC

If you want to get the row of the max, you'll probably need a sub-query. Something like:
SELECT *
FROM YourTable
WHERE id IN (
SELECT MAX(id) FROM YourTable GROUP BY alarmId, alarmUnit
)

Try:
SELECT * FROM table WHERE id IN
(SELECT MAX(id) FROM table GROUP BY alarmId, alarmUnit)

Maybe try something like the following:
SELECT id,name,alarmId,alarmUnit,alarmLevel
FROM table
WHERE id IN (SELECT Max(id) FROM table GROUP BY alarmId, alarmUnit)
You may have to include alarmId and alarmUnit in the sub query select.

select id, name, alarmID, alarmUnit, alarmLevel
from (select max(id) as id
from table
group by alarmID, alarmUnit) maxID
inner join table
on table.id = maxID.id

Related

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]

Get all items with min values SQL Server

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

How to reverse the table that comes from SQL query which already includes ORDER BY

Here is my query:
SELECT TOP 8 id, rssi1, date
FROM history
WHERE (siteName = 'CCL03412')
ORDER BY id DESC
This the result:
How can I reverse this table based on date (Column2) by using SQL?
You can use the first query to get the matching ids, and use them as part of an IN clause:
SELECT id, rssi1, date
FROM history
WHERE id IN
(
SELECT TOP 8 id
FROM history
WHERE (siteName = 'CCL03412')
ORDER BY id DESC
)
ORDER BY date ASC
You could simply use a sub-query. If you apply a TOP clause the nested ORDER BY is allowed:
SELECT X.* FROM(
SELECT TOP 8 id, Column1, Column2
FROM dbo.History
WHERE (siteName = 'CCL03412')
ORDER BY id DESC) X
ORDER BY Column2
Demo
The SELECT query of a subquery is always enclosed in parentheses. It
cannot include a COMPUTE or FOR BROWSE clause, and may only include an
ORDER BY clause when a TOP clause is also specified.
Subquery Fundamentals
try the below :
select * from (SELECT TOP 8 id, rssi1, date
FROM history
WHERE (siteName = 'CCL03412')
ORDER BY id DESC ) aa order by aa.date DESC
didn't run it, but i think it should go well
WITH cte AS
(
SELECT id, rssi1, date, RANK() OVER (ORDER BY ID DESC) AS Rank
FROM history
WHERE (siteName = 'CCL03412')
)
SELECT id, rssi1, date
FROM cte
WHERE Rank <= 8
ORDER BY Date DESC
I have not run this but i think it will work. Execute and let me know if you face error
select id, rssi1, date from (SELECT TOP 8 id, rssi1, date
FROM history
WHERE (siteName = 'CCL03412')
ORDER BY id DESC) order by date ;

Select the first instance of a record

I have a table, myTable that has two fields in it ID and patientID. The same patientID can be in the table more than once with a different ID. How can I make sure that I get only ONE instance of every patientID.?
EDIT: I know this isn't perfect design, but I need to get some info out of the database and today and then fix it later.
You could use a CTE with ROW_NUMBER function:
WITH CTE AS(
SELECT myTable.*
, RN = ROW_NUMBER()OVER(PARTITION BY patientID ORDER BY ID)
FROM myTable
)
SELECT * FROM CTE
WHERE RN = 1
It sounds like you're looking for DISTINCT:
SELECT DISTINCT patientID FROM myTable
you can get the same "effect" with GROUP BY:
SELECT patientID FROM myTable GROUP BY patientID
The simple way would be to add LIMIT 1 to the end of your query. This will ensure only a single row is returned in the result set.
WITH CTE AS
(
SELECT tableName.*,ROW_NUMBER() OVER(PARTITION BY patientID ORDER BY patientID) As 'Position' FROM tableName
)
SELECT * FROM CTE
WHERE
Position = 1

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.