How can I add ROW numbers to this query result?
SELECT DISTINCT
VehicleSpecs.SubmittedById,
COUNT(VehicleSpecs.SubmittedById) AS NumCars,
aspnet_Users.UserName
FROM
VehicleSpecs
INNER JOIN aspnet_Users ON VehicleSpecs.SubmittedById = aspnet_Users.UserId
WHERE
(LEN(VehicleSpecs.SubmittedById) > 0)
GROUP BY
VehicleSpecs.SubmittedById,
aspnet_Users.UserName
ORDER BY
NumCars DESC
Add: ROW_NUMBER() OVER (ORDER BY NumCars)
EDIT:
WITH t1 AS
( SELECT DISTINCT
VehicleSpecs.SubmittedById ,
COUNT(VehicleSpecs.SubmittedById) AS NumCars ,
aspnet_Users.UserName
FROM VehicleSpecs
INNER JOIN aspnet_Users ON VehicleSpecs.SubmittedById = aspnet_Users.UserId
WHERE ( LEN(VehicleSpecs.SubmittedById) > 0 )
GROUP BY VehicleSpecs.SubmittedById ,
aspnet_Users.UserName
)
SELECT ROW_NUMBER() OVER ( ORDER BY NumCars ), *
FROM t1
ORDER BY NumCars
Wrap you entire query in a sub query and add row_number in the outer query.
select *, row_number() over(order by (select 0)) as rn
from
(
select distinct -- your columns
from YourTable
) as T
order by NumCars desc
Related
Currently trying to figure out how to implement a SQL LEFT OUTER JOIN while using the SQL WITH AS clause. My code breaks down into 3 SELECT statements while using the same table, then using LEFT OUTER JOIN to merge another table on the id.
I need 3 SELECT statements before joining because I need a SELECT statement to grab the needed columns, ROW RANK the time, and set WHERE clause for the ROW RANK.
SELECT *
(
WITH employee AS
(
SELECT id, name, department, code, time, reporttime, scheduled_time
FROM table1 AS a
WHERE department = "END"
),
employe_v2 as
(
SELECT address
,ROW_NUMBER() OVER (PARTITION BY id ORDER BY time desc, reporttime desc, scheduled_time desc) AS row_rank
FROM table1 AS b
)
SELECT *
FROM employee, employee_v2
WHERE row_rank = 1
) t1
LEFT OUTER JOIN
(
SELECT b.id, b.new_code, b.date
FROM table2 AS b
WHERE b.newcode != "A"
) t2
ON t1.id = t2.id
Group BY t1.id, t1.name, t1.department, t1.code, t1.time, t1.reporttime,
t1.scheduled_time, t1.row_rank, t2.id, t2.new_code, t2.date
How I could fix my code?
not sure if group by is needed, i see no aggregation whatsover
but if it's something you need , you can add at the end of final select and ofcourse you have to take care of columns/aggregation in select
nevertheless you can simplify your query as below :
with employee as (
select * from (
select id, name, department, code, time, reporttime, scheduled_time, address
,row_number() over (partition by id order by time desc, reporttime desc, scheduled_time desc) AS row_rank
from table1
) t where row_rank =1
)
select t1.*, b.id, b.new_code, b.date
from employee t1
left join table2 as t2
on t1.id = t2.id
where t2.newcode != "A"
Here is my case,
SELECT
A.TAB1_COL1,B.TAB2_COL4,C.TAB2_COL4
FROM TABLE1 A,
LEFT OUTER JOIN
(SELECT * FROM
(SELECT TAB2_COL1, TAB2_COL2, TAB2_COL4, ROW_NUMBER() OVER (PARTITION BY TAB2_COL1,TAB2_COL2 ORDER BY TAB2_COL3 DESC ) AS ROW_NUM
FROM TABLE2
WHERE TAB2_COL2=2
) WHERE ROW_NUM=1
) B ON A.TAB1_COL1=B.TAB2_COL1
LEFT OUTER JOIN
(SELECT * FROM
(SELECT TAB2_COL1, TAB2_COL2, TAB2_COL4, ROW_NUMBER() OVER (PARTITION BY TAB2_COL1,TAB2_COL2 ORDER BY TAB2_COL3 DESC ) AS ROW_NUM
FROM TABLE2 WHERE TAB2_COL2=5
) WHERE ROW_NUM=1
) C ON A.TAB1_COL1=C.TAB2_COL1 AND A.TAB1_COL2=C.TAB2.COL5
LEFT OUTER JOIN
(SELECT * FROM
(SELECT TAB2_COL1, TAB2_COL2, TAB2_COL4, ROW_NUMBER() OVER (PARTITION BY TAB2_COL1,TAB2_COL2 ORDER BY TAB2_COL3 DESC ) AS ROW_NUM
FROM TABLE2 WHERE TAB2_COL2=8
) WHERE ROW_NUM=1
) D ON A.TAB1_COL1=D.TAB2_COL1
This code will work.But, I'm left joining with same table multiple times. In my case, it was around 25 times. Reference table has around 200 million records. Partition to remove dups is taking much time.
Any other effective way of writing to make it process faster. Kindly help.
Thanks
If I understand correctly, you can use conditional aggregation:
select t1.tab1_col1,
max(case when tab2_col2 = 2 then tab2_col4 end),
max(case when tab2_col2 = 5 then tab2_col4 end),
max(case when tab2_col2 = 8 then tab2_col4 end)
from table1 t1 left join
(select t2.*,
row_number() over (partition by tab2_col1, tab2_col2 order by tab2_col3 desc) as seqnum
from table2 t2
) t2
on t1.tab1_col1 = t2.tab2_col1
group by t1.tab1_col1;
I am trying to get an SQL statement to work which will show a list of users in the database and their last action.
The current table format is;
tblUser:
id, username, password
tblAction:
id, uid, action, date
The SQL statment I have at present is;
SELECT *
FROM tblUser
FULL OUTER JOIN Location
ON tblUser.id=tblAction.uid
WHERE action IS NOT NULL
ORDER BY date DESC
I have used limit 1 but this hasn't worked.
I have also tried;
SELECT *
FROM tblAction T1
WHERE date = (
SELECT max(date)
FROM tblUser T2
WHERE T2.uid=T1.id
Please could someone help me?
This is an SQL command to be executed in an admin panel in PHP and is not MySQL.
Use ROW_NUMBER:
;WITH CTE AS
(
SELECT U.*,
A.[action],
A.[date],
RN = ROW_NUMBER() OVER(PARTITION BY U.id ORDER BY A.[date] DESC)
FROM tblUser U
LEFT JOIN tblAction A
ON U.id = A.uid
)
SELECT *
FROM CTE
WHERE RN = 1;
try use RANK()/DENSE_RANK()/ROW_NUMBER()
FIDDLE DEMO
RANK:
;WITH CTE AS
(
SELECT a.*,
b.action,
b.date,
Rk = RANK() OVER(PARTITION BY a.id ORDER BY b.[date] DESC)
FROM tblUser a
LEFT JOIN tblAction b
ON a.id = b.uid
)
SELECT *
FROM CTE
WHERE Rk = 1;
i need an sql query which should return the master table entry and its child table entry (the latest one entry only). I used inner join for this. But i its not working fine.
Can anyone give a give me a proper query for this
Thanks in advance
In SQLServer2005+ use option with OUTER APPLY operator
SELECT *
FROM master t1 OUTER APPLY (
SELECT TOP 1 t2.Col1, t2.Col2 ...
FROM child t2
WHERE t1.Id = t2.Id
ORDER BY t2.CreatedDate DESC
) o
OR option with CTE and ROW_NUMBER() ranking function
;WITH cte AS
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY t1.Id ORDER BY t2.CreatedDate DESC) AS rn
FROM master t1 JOIN child t2 ON t1.Id = t2.Id
)
SELECT *
FROM cte
WHERE rn = 1
Try this,
SELECT ID, DATE
(
SELECT M.ID, C.DATE, ROW_NUMBER() OVER(PARTITION BY M.ID ORDER BY C.DATE DESC) RN
FROM MASTER M
JOIN CHILD C
ON C.ID = M.ID
) A
WHERE RN = 1
I have a complex query to populate data and after than
i have to join the data in the table to get the right result.
How to eliminate the join such that i do not have to define the table two times.
The join query being -
select t1.acc_no, t1.group_id, t1.remdt from #tbl t1
inner join (
select group_id, MAX(row_num) as max_row from #tbl group by group_id) t2
on t1.group_id= t2.group_id and t1.row_num=t2.max_row
now in the above query i have to decalre #tbl temp table.
How to get the same result such that i dont have to do using the join and do not have to write the same query twice.
My #tbl is populated using the sql -
select ReminderDt as 'rem dt', m.Group_Id, m.AccountNumber,
row_number() over (partition by group_id order by reminderdt asc) as seqnum
from ACE_AccsLevelTran t join ACE_AccsLevelMaster m on t.MasterAccNumber=m.AccountNumber where m.AssignedUser=7
Thanks
You can do this with a window function, row_number():
select t.acc_no, t.group_id, t.remdt
from (select t.*, ROW_NUMBER() over (partition by group_id order by row_num desc) as seqnum
from #tbl t
) t
where seqnum = 1;