selecting distinct data using group by in SQL - sql

I have an action log table which records when a registrant record was viewed by a compnay employee. I have an sql query like this:
SELECT [ID]
,[RegistrantID]
,[EmployeeID]
,[UserID]
,[CompanyID]
,[VacancyID]
,[Action]
,[ActionDate]
FROM [Hrge].[dbo].[hr_ActionLog]
where action = 4
and CompanyID = 3
order by ActionDate desc
and data is like this:
ID RegistrantID EmployeeID UserID CompanyID VacancyID Action ActionDate
1793 16295 15 16321 3 NULL 4 2013-08-04 16:45:40.457
1792 16292 15 16321 3 NULL 4 2013-08-04 16:45:33.003
1791 NULL 15 16321 3 NULL 3 2013-08-04 16:45:23.660
1790 16295 9 16289 3 NULL 4 2013-08-04 16:45:09.543
1789 16295 9 16289 3 NULL 4 2013-08-04 16:45:00.817
1799 16295 15 16321 3 NULL 4 2012-08-04 16:45:40.457
1797 16292 15 16321 3 NULL 4 2012-08-04 16:45:33.003
1796 NULL 15 16321 3 NULL 3 2012-08-04 16:45:23.660
1795 16295 9 16289 3 NULL 4 2012-08-04 16:45:09.543
1794 16295 9 16289 3 NULL 4 2012-08-04 16:45:00.817
I want to select distinct views to a registrantid record ( the first ones) in one year. if a registrant was viewed 10 tmes a year then it will show only first time it was viewed. If it was viewed 10 times by an employeed in 2 years then it will show first time it was viewed. if it was viewed by 2 employees of same company 10 times in one year then it first time viewed record will be shown. if it was seen 10 times by 2 employees of two different companies in one year then first record of two companies will be shown. do i need to use group by or what ?

Use the ranking function ROW_NUMBER with PARTITION BY RegistrantID ORDER BY ActionDate to get the first date for each RegistrantID:
WITH CTE AS
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY RegistrantID
ORDER BY ActionDate) AS RN
FROM [Hrge].[dbo].[hr_ActionLog]
WHERE action = 4
AND CompanyID = 3
)
SELECT [ID]
,[RegistrantID]
,[EmployeeID]
,[UserID]
,[CompanyID]
,[VacancyID]
,[Action]
,[ActionDate]
FROM CTE
WHERE RN = 1;
SQL Fiddle Demo

Related

Find sum of hours for each date worked

I have a table of timesheet entries set up like this:
id
job_id
employee_id
hours_worked
date_worked
1
1
111
8
2022-10-01
2
1
222
8
2022-10-01
3
1
222
8
2022-10-02
4
2
222
8
2022-10-03
5
2
111
8
2022-10-04
6
2
222
5
2022-10-05
7
3
111
8
2022-10-04
8
4
333
8
2022-10-07
9
4
111
3
2022-10-09
I'm trying to find the sum of hours for the first, second, third etc dates that work was done on each job
Ideally I'd like something like this:
job_id
Day1_hours
Day2_hours
Day3_hours
1
16
8
0
2
8
8
5
3
8
0
0
4
8
3
0
The trouble I'm running into is that there can be multiple employees working on each day of the job, so using a query to select the min(date_worked) greater than a subquery for min(date_worked) is sometimes giving me the same dates. There are sometimes days in between work done on a job, so I can't just add a day to the minimum value and check hours for that date.
How can I find the sum of hours_worked for the first date_worked, then the second, third etc?
PIVOT's are great but conditional aggregations offer a bit more flexibility
Example
Select job_id
,[Day1_Hours] = sum( case when DN=1 then hours_worked else 0 end)
,[Day2_Hours] = sum( case when DN=2 then hours_worked else 0 end)
,[Day3_Hours] = sum( case when DN=3 then hours_worked else 0 end)
From ( Select *
,DN = dense_rank() over (partition by job_id order by date_worked)
From YourTable
) A
Group By Job_ID
select job_id
,[1] as day1_hours
,[2] as day2_hours
,[3] as day3_hours
from (
select job_id
,hours_worked
,dense_rank() over(partition by job_id order by date_worked) as days
from t
) t
pivot (sum(hours_worked) for days in([1],[2],[3])) p
job_id
day1_hours
day2_hours
day3_hours
1
16
8
null
2
8
8
5
3
8
null
null
4
8
3
null
Fiddle

Get earliest value from a column with other aggregated columns in postgresql

I have a very simple stock ledger dataset.
1. date_and_time store_id product_id batch opening_qty closing_qty inward_qty outward_qty
2. 01-10-2021 14:20:00 56 a 1 5 1 0 4
3. 01-10-2021 04:20:00 56 a 1 8 5 0 3
4. 02-10-2021 15:30:00 56 a 1 9 2 1 8
5. 03-10-2021 08:40:00 56 a 2 2 6 4 0
6. 04-10-2021 06:50:00 56 a 2 8 4 0 4
Output I want:
select date, store_id,product_id, batch, first(opening_qty),last(closing_qty), sum(inward_qty),sum(outward_qty)
e.g.
1. date store_id product_id batch opening_qty closing_qty inward_qty outward_qty
2. 01-10-2021 56 a 1 8 1 0 7
I am writing a query using First_value window function and tried several others but not able to get the out put I want.
select
date,store_id,product_id,batch,
FIRST_VALUE(opening_total_qty)
OVER(
partition by date,store_id,product_id,batch
ORDER BY created_at
) as opening__qty,
sum(inward_qty) as inward_qty,sum(outward_qty) as outward_qty
from table
group by 1,2,3,4,opening_total_qty
Help please.
As your expected result is one row per group of rows with the same date, you need aggregates rather than window functions which provide as many rows as the ones filtered by the WHERE clause. You can try this :
SELECT date_trunc('day', date),store_id,product_id,batch
, (array_agg(opening_qty ORDER BY datetime ASC))[1] as opening__qty
, (array_agg(closing_qty ORDER BY datetime DESC))[1] as closing_qty
, sum(inward_qty) as inward_qty
, sum(outward_qty ) as outward_qty
FROM table
GROUP BY 1,2,3,4
see the test result in dbfidle.

Simple data, Complex query on SQL Server

I need to make a query over an SQL Server table but I don't know exactly how.
Consider this table (the real table is much more complex, Ord1 and Ord2 are dates that could be null, but i simplified it to this case):
Data of MyTable
ID MaqID Ord1 Ord2
------------------------
1 144 4 3
2 144 2 1
3 12 2 3
4 144 3 5
5 12 3 1
6 144 4 2
7 12 2 4
8 144 2 3
9 12 1 5
10 12 3 2
I need records for specific MaqID in Specific Order. I get that with this Query:
SELECT * FROM myTable WHERE MaqID=144 ORDER BY MaqID, Order1 DESC, Order2
Wich give me:
ID MaqID Ord1 Ord2
------------------------
6 144 4 2
1 144 4 3
4 144 3 5
2 144 2 1
8 144 2 3
Now, I need a single query that, for each MaqID, return the first ID for each subquery following above order. The result should be:
Expected result
MaqID ID
-----------
144 6
12 5
I have already try distinct conbination of TOP a MAX, but TOP result only one result and i need one for each MaqID, and for Max I have not field to maximize.
To sumarize: I need the first ID for each MaqID from a subquery in a specific order
Any ideas? Thanks!
You can do this using row_number():
select t.*
from (select t.*,
row_number() over (partition by macid Order1 DESC, Order2) as seqnum
from mytable t
) t
where seqnum = 1;

Need hierarichal data from 3 tables in SQL Server

I have following tables:
UserMaster:
UserId Int, UserName Varchar(200),AddedBy Int
UserId EmpName AddedBy
1 admin 0
2 SubAdmin1 1
3 SubAdmin2 1
4 Vikas 2
5 Mohit 4
6 Atul 5
7 Vishal 6
8 Mani 3
9 Sunny 8
SalesMaster:
SalesId Int, UserId Int (FK_UserMaster_UserId) , Price Int
SalesId UserId Price
1 1 100
2 2 200
3 3 300
4 4 500
5 5 100
6 6 200
7 7 111
8 8 222
9 9 333
Case 1: Now I want the price total of all the users who are under the one particular user and its own price also.
Means If i consider UserId=1 , Then the price will be calculated for all users where Column value in AddedBy=1
and their lower level employees.
Means the total Price of users will be calulated for the users having UserId are: 1,2,3,4,5,6,7,8,9.
Case 2: Similarly, If i want to calculate the total price under UserId=3(SubAdmin2) then the total price from the salesMaster will be calculated for the Users having UserId are: 3,8,9
The Result of first Case should be:
UserId Price
1 2066
The Result of Second Case should be:
UserId Price
3 300+222+333
Please Help
Thanks & Regards
Nitin
with cte as (
select #UserId as UserId
union all
select um.UserId
from UserMaster as um
inner join cte as c on c.UserId = um.AddedBy
)
select sum(s.Price)
from cte as c
inner join SalesMaster as s on s.UserId = c.UserId
sql fiddle demo

How to do grouping by a date span?

Conside this Table Structure.
Key ID VISITDATE
1 1 2011-01-07
2 1 2011-01-09
3 2 2011-01-10
4 1 2011-01-12
5 3 2011-01-12
6 1 2011-01-15
7 2 2011-01-21
9 1 2011-02-28
10 2 2011-03-21
11 1 2011-01-06
I need to get all the IDs,Key,min(VisitDate) where VisitDate is within 10 days span?if you have two visits within 10 days one row need to be there in the result.
Result
KEY ID VISITDATE
11 1 2011-01-06
3 2 2011-01-10
5 3 2011-01-12
7 2 2011-01-21
9 1 2011-02-28
10 2 2011-03-21
Can this be done without a self join. i have a query which does a self join with the table on ID and check the datediff.is there a better solution?can we use recursive CTE here?
EDIT
Prefer a solution which can use the index on date column
Yes a CTE would work nicely for this (everything with me is CTEs lately)...
;WITH TenDayVisits
AS (
SELECT
ID
,MIN(VisitDate) AS VisitDate
FROM Visits
GROUP BY ID
UNION ALL
SELECT
t.ID
,v.VisitDate
FROM Visits AS v
JOIN TenDayVisits AS t ON v.ID = t.ID
AND DATEDIFF(dd,t.Visitdate,v.VisitDate) > 10
)
SELECT
DISTINCT
v.[key]
,t.id
,t.VisitDate
FROM TenDayVisits as T
JOIN Visits AS v ON t.id = v.id
AND t.VisitDate = v.VisitDate