Putoch
asked on
Finding the nth value in a colunm in t-sql
Hi,
This is really confusing me, i have been looking at different solutions and i have been looking up stuff but i can't see how the code below will not work.
I have created the table and inserts and the select statement i am using, I just want to find the 2nd largest id in this table. this is the example below:
Create table testtable (
Account_id nvarchar(10),
colunm_id int not null)
INSERT INTO [testtable]values (75004,19323);
INSERT INTO [testtable]values (75004,215459);
INSERT INTO [testtable]values (75004,217988);
INSERT INTO [testtable]values (75004,365446);
INSERT INTO [testtable]values (75004,368770);
SELECT a.colunm_id
from testtable a
INNER JOIN (Select max(b.colunm_ID)maxid
from testtable b
--this will choose the max id in the table and the query above will pick the next value.
where b.colunm_id not in
(select top 1 c.colunm_id
from testtable c
where c.account_id = b.account_id
order by c.colunm_id desc))
subq on subq.maxid = a.colunm_id
where a.account_id = 75004
However if i insert these exaples instead
INSERT INTO [testtable]values (123456,19323);
INSERT INTO [testtable]values (123456,45824);
INSERT INTO [testtable]values (123456,859785);
INSERT INTO [testtable]values (123456,444666);
INSERT INTO [testtable]values (123456,598752);
and find the second largest id for 123456 it works??? what am i doing wrong please any advise would be appriciated its driving me mad!
Kind Regards,
Elaine.
This is really confusing me, i have been looking at different solutions and i have been looking up stuff but i can't see how the code below will not work.
I have created the table and inserts and the select statement i am using, I just want to find the 2nd largest id in this table. this is the example below:
Create table testtable (
Account_id nvarchar(10),
colunm_id int not null)
INSERT INTO [testtable]values (75004,19323);
INSERT INTO [testtable]values (75004,215459);
INSERT INTO [testtable]values (75004,217988);
INSERT INTO [testtable]values (75004,365446);
INSERT INTO [testtable]values (75004,368770);
SELECT a.colunm_id
from testtable a
INNER JOIN (Select max(b.colunm_ID)maxid
from testtable b
--this will choose the max id in the table and the query above will pick the next value.
where b.colunm_id not in
(select top 1 c.colunm_id
from testtable c
where c.account_id = b.account_id
order by c.colunm_id desc))
subq on subq.maxid = a.colunm_id
where a.account_id = 75004
However if i insert these exaples instead
INSERT INTO [testtable]values (123456,19323);
INSERT INTO [testtable]values (123456,45824);
INSERT INTO [testtable]values (123456,859785);
INSERT INTO [testtable]values (123456,444666);
INSERT INTO [testtable]values (123456,598752);
and find the second largest id for 123456 it works??? what am i doing wrong please any advise would be appriciated its driving me mad!
Kind Regards,
Elaine.
It is returning the correct values...
I think this would be a more straight-forward way to do the same thing:
SELECT Max(colunm_id)
FROM testtable a
WHERE colunm_id < (SELECT Max(colunm_id) from name where account_id= a.account_id)
and a.account_id = 75004
SELECT Max(colunm_id)
FROM testtable a
WHERE colunm_id < (SELECT Max(colunm_id) from name where account_id= a.account_id)
and a.account_id = 75004
ASKER
Thanks for your comments folks,
Aneeshattingal, have you inserted both inserts? and it still works? because it does not for me for some reason? i can not understand this.
ksaul, I am getting the following error when i run your code:
'Invalid object name 'name'.' is this code running fine for you? i am using SQL SERVER 2005
Thanks for you help guys
Aneeshattingal, have you inserted both inserts? and it still works? because it does not for me for some reason? i can not understand this.
ksaul, I am getting the following error when i run your code:
'Invalid object name 'name'.' is this code running fine for you? i am using SQL SERVER 2005
Thanks for you help guys
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
My God i never even seen the change in the table name i am going blind lookin at this, i know its simple code but that was what was annoying me.
Sorry for that.
Ok i see this works great with just the two colunm but if i add in any more fields it is bringing back all the entries!
for example if i drop the table angain and add in more field names:
Drop table testtable
Create table testtable (
Account_id nvarchar(10),
colunm_id int not null,
status_id smallint not null,
status_date datetime not null)
INSERT INTO [testtable]values (75004,19323,1,'2006-04-29 12:48:37.000');
INSERT INTO [testtable]values (75004,215459,2,'2006-12-1 3 11:37:42.000');
INSERT INTO [testtable]values (75004,217988,1,'2006-12-1 5 13:46:10.000');
INSERT INTO [testtable]values (75004,365446,2,'2007-06-2 0 08:59:30.000');
INSERT INTO [testtable]values (75004,368770,1,'2007-06-2 5 11:22:07.000');
Now if i run this Statement now this works as i want it to:
SELECT * FROM testtable a
INNER JOIN (SELECT MAX(b.colunm_ID)maxid
FROM testtable b
--this will choose the max id in the table and the query above will pick the next value.
WHERE b.colunm_id NOT IN
(SELET TOP 1 c.colunm_id
FROM testtable c
WHERE c.account_id = b.account_id
ORDER BY c.colunm_id desc))
subq on subq.maxid = a.colunm_id
WHERE a.account_id = 75004
BUT if i now insert these rows and run the same statement again it will return noting!
INSERT INTO [testtable]values (123456,19323,1,'2007-04-2 9 12:48:37.000');
INSERT INTO [testtable]values (123456,45824,2,'2007-04-2 9 12:48:37.000');
INSERT INTO [testtable]values (123456,859785,1,'2006-04- 29 12:48:37.000');
INSERT INTO [testtable]values (123456,444666,2,'2006-04- 29 12:48:37.000');
INSERT INTO [testtable]values (123456,598752,1,'2005-04- 29 12:48:37.000');
AND if I use the statement you posted for me Ksaul and add in the extra fields i want to see i end up returning all the rows in the table rahther then just the second highest id and its occurances.
SELECT Max(colunm_id), account_id, status_id, status_date
FROM testtable a
WHERE colunm_id < (SELECT Max(colunm_id) from testtable where account_id= a.account_id)
and a.account_id = 75004
Group by account_id, status_id, status_date
Sorry i have tried various waus of running this and i either get an error back or all the row!!
Thanks,
Putoch
Sorry for that.
Ok i see this works great with just the two colunm but if i add in any more fields it is bringing back all the entries!
for example if i drop the table angain and add in more field names:
Drop table testtable
Create table testtable (
Account_id nvarchar(10),
colunm_id int not null,
status_id smallint not null,
status_date datetime not null)
INSERT INTO [testtable]values (75004,19323,1,'2006-04-29
INSERT INTO [testtable]values (75004,215459,2,'2006-12-1
INSERT INTO [testtable]values (75004,217988,1,'2006-12-1
INSERT INTO [testtable]values (75004,365446,2,'2007-06-2
INSERT INTO [testtable]values (75004,368770,1,'2007-06-2
Now if i run this Statement now this works as i want it to:
SELECT * FROM testtable a
INNER JOIN (SELECT MAX(b.colunm_ID)maxid
FROM testtable b
--this will choose the max id in the table and the query above will pick the next value.
WHERE b.colunm_id NOT IN
(SELET TOP 1 c.colunm_id
FROM testtable c
WHERE c.account_id = b.account_id
ORDER BY c.colunm_id desc))
subq on subq.maxid = a.colunm_id
WHERE a.account_id = 75004
BUT if i now insert these rows and run the same statement again it will return noting!
INSERT INTO [testtable]values (123456,19323,1,'2007-04-2
INSERT INTO [testtable]values (123456,45824,2,'2007-04-2
INSERT INTO [testtable]values (123456,859785,1,'2006-04-
INSERT INTO [testtable]values (123456,444666,2,'2006-04-
INSERT INTO [testtable]values (123456,598752,1,'2005-04-
AND if I use the statement you posted for me Ksaul and add in the extra fields i want to see i end up returning all the rows in the table rahther then just the second highest id and its occurances.
SELECT Max(colunm_id), account_id, status_id, status_date
FROM testtable a
WHERE colunm_id < (SELECT Max(colunm_id) from testtable where account_id= a.account_id)
and a.account_id = 75004
Group by account_id, status_id, status_date
Sorry i have tried various waus of running this and i either get an error back or all the row!!
Thanks,
Putoch
ASKER
Ok i was looking at Row_number and some other new functions in SQL SERVER 2005 ( RANK, DENSE_RANK, and NTILE) however , I was reading a book and i came across a quote saying ''you can't use the ROW_NUMBER() (or any of the other ranking functions) in the WHERE clause'' but advised me to Create a View instead. So i
did a Select statement using Row_number to get an extra column to rank each account_id
then created a view on this statement and i can do a select on the view where ranking = 2!
--Adding in Rank to table
SELECT Account_id, status_date, status_id, colunm_id,
ROW_NUMBER() OVER (PARTITION BY account_id ORDER BY colunm_id DESC) AS RANKING
FROM testtable AS tab
--Create View
create view vwtab as
SELECT Account_id, status_date, status_id, colunm_id,
ROW_NUMBER() OVER (PARTITION BY account_id ORDER BY colunm_id DESC) AS RANKING
FROM testtable AS tab
--Statement
select * from vwtab where RANKING = 2
So this will allow me to see all account_id and their second highest input into the table.
Thank you for your time and help
Putoch
did a Select statement using Row_number to get an extra column to rank each account_id
then created a view on this statement and i can do a select on the view where ranking = 2!
--Adding in Rank to table
SELECT Account_id, status_date, status_id, colunm_id,
ROW_NUMBER() OVER (PARTITION BY account_id ORDER BY colunm_id DESC) AS RANKING
FROM testtable AS tab
--Create View
create view vwtab as
SELECT Account_id, status_date, status_id, colunm_id,
ROW_NUMBER() OVER (PARTITION BY account_id ORDER BY colunm_id DESC) AS RANKING
FROM testtable AS tab
--Statement
select * from vwtab where RANKING = 2
So this will allow me to see all account_id and their second highest input into the table.
Thank you for your time and help
Putoch