SQL Select Distinct Top5 with Order By and Where - sql

I have a table where Employees can check assets and each of their checks is recorded in a table.
Now I want to extract the 5 last checked Asset_Ids for a given employee. He might have checked the same asset more than once, each check is recorded in a table -EmployeeLog-
Basically my table has 3 columns :
Employee_ID
DateChecked
Asset_ID
1
06/10/2021 10:56:22
1
1
06/10/2021 14:58:25
1
1
02/10/2021 13:56:22
2
1
06/10/2021 08:56:22
1
1
04/10/2021 03:56:22
1
1
06/10/2021 02:56:22
3
1
06/10/2021 15:56:22
2
1
03/10/2021 03:56:22
5
1
06/10/2021 03:56:22
5
I have below query which lists Asset_IDs by check date, but I have to apply distinct and top 5 to this list which I couldn't, any help appreciated.
SELECT Asset_ID
FROM EmployeeLog
WHERE EmployeeID = #Emp_ID AND Asset_ID != '00000000-0000-0000-0000-000000000000'
ORDER BY EmployeeLog.DateChecked Desc

You can do a GROUP BY, and order by first (or last) date.
SELECT Asset_ID
FROM EmployeeLog
WHERE EmployeeID = #Emp_ID AND Asset_ID != '00000000-0000-0000-0000-000000000000'
GROUP BY Asset_ID
ORDER BY MIN(EmployeeLog.DateChecked) Desc
To get the first 5 rows only, do SELECT TOP 5 Asset_ID etc.

Related

Getting count of last records of 2 columns SQL

I was looking for a solution for the below mentioned scenario.
So my table structure is like this ; Table name : energy_readings
equipment_id
meter_id
readings
reading_date
1
1
100
01/01/2022
1
1
200
02/01/2022
1
1
null
03/01/2022
1
2
100
01/01/2022
1
2
null
04/01/2022
2
1
null
04/01/2022
2
1
399
05/01/2022
2
2
null
02/01/2022
So from this , I want to get the number of nulls for the last record of same equipment_id and meter_id. (Should only consider the nulls of the last record of same equipment_id and meter_id)
EX : Here , the last reading for equipment 1 and meter 1 is a null , therefore it should be considered for the count. Also the last reading(Latest Date) for equipment 1 and meter 2 is a null , should be considered for count. But even though equipment 2 and meter 1 has a null , it is not the last record (Latest Date) , therefore should not be considered for the count.
Thus , this should be the result ;
equipment_id
Count
1
2
2
1
Hope I was clear with the question.
Thank you!
You can use CTE like below. CTE LatestRecord will get latest record for equipment_id & meter_id. Later you can join it with your current table and use WHERE to filter out record with null values only.
;WITH LatestRecord AS (
SELECT equipment_id, meter_id, MAX(reading_date) AS reading_date
FROM energy_readings
GROUP BY equipment_id, meter_id
)
SELECT er.meter_id, COUNT(1) AS [Count]
FROM energy_readings er
JOIN LatestRecord lr
ON lr.equipment_id = er.equipment_id
AND lr.meter_id = er.meter_id
AND lr.reading_date = er.reading_date
WHERE er.readings IS NULL
GROUP BY er.meter_id
with records as(
select equ_id,meter_id,reading_date,readings,
RANK() OVER(PARTITION BY meter_id,equ_id
order by reading_date) Count
from equipment order by equ_id
)
select equ_id,count(counter)
from
(
select equ_id,meter_id,reading_date,readings,MAX(Count) as counter
from records
group by meter_id,equ_id
order by equ_id
) where readings IS NULL group by equ_id
Explanation:-
records will order data by reading_date and will give counting as 1,2,3..
select max of count from records
select count of counter where reading is null
Partition by will give counting as shown in image
Result

Select rows with max date from table

I have such table and need table 2 result. I am trying to select rows with max date grouped by project_id and ordered by id. And result table must have id column. Tried such request:
SELECT MAX(charges.id) as id,
"charges"."profile_id", MAX(failed_at) AS failed_at
FROM "charges"
GROUP BY "charges"."profile_id"
ORDER BY "charges"."id" ASC
And have error:
ERROR: column "charges.id" must appear in the GROUP BY clause or be used in an aggregate function)
Example table
id
profile_id
failed_at
1
1
01.01.2021
2
1
01.02.2021
3
1
01.03.2021
4
2
01.06.2021
5
2
01.05.2021
6
2
01.04.2021
Needed result
id
profile_id
failed_at
3
1
01.03.2021
4
2
01.06.2021
SELECT charges.*
FROM charges
INNER JOIN
(
SELECT
profile_id,
MAX(charges.failed_at) AS MaxFailed_at
FROM charges
GROUP BY profile_id
) AS xQ ON charges.profile_id = xQ.profile_id AND charges.failed_at = xQ.MaxFailed_at

How to get all columns when you do group by for multiple columns?

Here is my table
UserDetail
Id UserId CourseId SubjectId TeacherCode RDate status
1 1 1 1 1 08/02/2016 Waiting
2 1 1 1 2 08/01/2016 Recceived
3 1 1 1 3 08/02/2016 Processed
4 1 1 2 1 08/03/2016 Recceived
5 1 1 2 2 08/04/2016 Processed
6 1 2 1 3 08/05/2016 Processed
7 1 2 2 1 08/06/2016 Processed
User can have multiple courses,multiple subjects.One teacher can teach multiple subject.I want to fetch all column from table, base on distinct userid,courseid and subjectid.Out of 7 row,want to show only 4 rows.
Any one record from below
Id UserId CourseId SubjectId TeacherCode RDate status
1 1 1 1 1 08/02/2016 Waiting
2 1 1 1 2 08/01/2016 Recceived
3 1 1 1 3 08/02/2016 Processed
If we pick teachercode 1,then rdate to be 08/02/2016 and status to be Waiting
neither Recceived nor Processed.
Any one from below
Id UserId CourseId SubjectId TeacherCode RDate status
4 1 1 2 1 08/03/2016 Recceived
5 1 1 2 2 08/04/2016 Processed
How to do that?
You gotta know which rows of that distincted datas you want to choose. First rows ? Last rows ?
Since for every group of distincted data would be multiple rows so you mist choose which row you want.
I assume you want the first row from every distincted group. You can do it like below:
Select first(Id) AS Id, first(UserId) AS UserId, first(CrouseId) AS CourseId, first(SubjectId) AS SubjectId, first(TeacherId) AS TescherId,first(RDate) AS RDate, first(status) as status
FROM UserDetail
Group By UserId, CourseId, SubjectId
In sql2005+, do it like below:
WITH temp AS (
SELECT *,
ROW_NUMBER() OVER(PARTITION BY UserId,CourseId,SubjectId ORDER BY Id) AS rn FROM UserDetail)
SELECT t.*
FROM temp t
WHERE t.rn = 1
Or you can do it using inner select instead of WITH:
SELECT *
FROM (SELECT *,
ROW_NUMBER() OVER(PARTITION BY UserId,CourseId,SubjectId ORDER BY Id) AS rn FROM UserDetail)
WHERE rn = 1

Find the Product Number

I am trying to find the product number/product name based on the following set of conditions:
Select top 1 productnumber in xyz table
where product number in (1,2,3) order by filingdate --only if the last filing date has this product number
If product number in (4,5,6) for the last filing date nothing should be selected
If product number not in (4,5,6) for the last filing, then select the next top 1 productnumber
where prodcutnumber in (1,2,3) order by filingdate
how can i achieve this in a single query, i tried case statement bu i am stuck with it.
Sample data:
pnumber fnumber fdate
1 1 12/31
2 1 12/10
1 2 12/10
4 2 12/11
5 2 12/12
7 3 12/12
1 3 12/11
the results should be
pnumber fnumber fdate
1 1 12/31
1 2 12/10
1 3 12/11
Try by giving datatype as varchar for fdate.
SELECT id,
funum,
fdate
FROM (SELECT Row_number()
OVER(
partition BY funum
ORDER BY id) rn,
*
FROM t)p
WHERE rn = 1

Return results where first entry is 1 and all subsequent rows are 0

I m working on weird SQL query
Patient_ID Count order_no
1 1 1
2 1 2
2 0 3
2 0 4
3 1 5
3 0 6
where I need to count the patient as above, for every new patient , the count column is 1.
If repeated , the below entry it should be 0
I m confused how should make that work in SQL
In order to make the first entry 1 and all subsuqent entries 0, I believe you need a ranking with partition by the order number. Please checkout the sqlfiddle below to test results.
http://www.sqlfiddle.com/#!3/4e2e2/17/0
SELECT
patient_id
,CASE WHEN r.rank = 1
THEN 1
ELSE 0
END
, order_number
FROM
(
SELECT
order_number
,patient_id
,ROW_NUMBER() OVER (PARTITION BY patient_id ORDER BY order_number)[rank]
FROM
PatientTable
)r