Solved

SQL - Previous/Next Records

Posted on 2016-08-26
15
64 Views
Last Modified: 2016-09-29
I have a table with a GUID ID column and Firstname, Surname fields. I want to be able to select a record using the GUID and also select the previous/next record sorted by the Firstname and Surname fields. So for example, i

Capture2.PNG
In the example above, I want to select record c5875.... (Kevin) and have the previous/next sorted by the 2nd/3rd column and have it display John (prev) and Tracy (next).

Hope that makes sense.
0
Comment
Question by:John Smith
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
  • 3
  • +2
15 Comments
 
LVL 29

Expert Comment

by:Olaf Doschke
ID: 41771397
See LEAD() and LAG(), if you have SQL2008+

Bye, Olaf.
0
 
LVL 28

Expert Comment

by:Pawan Kumar
ID: 41771456
@Olaf Doschke - LEAD() and LAG() were available from SQL Server 2012.
https://msdn.microsoft.com/en-IN/library/hh213125.aspx


SQL Server 2012 introduces new analytical function LEAD() and LAG(). These functions accesses data from a subsequent row (for lead) and previous row (for lag) in the same result set without the use of a self-join .

NEXT Value Sample example - https://msbiskills.com/2012/07/19/t-sql-2/

Previous Value Sample example - https://msbiskills.com/2012/07/19/t-sql-1/

Enjoy !
0
 
LVL 41

Expert Comment

by:Sharath
ID: 41771459
To complete Olaf's suggestion.
select *,
       lag(FirstName) over (order by FirstName) Prev,
	   lead(FirstName) over (order by FirstName) Nxt
  from your_table

Open in new window

0
NFR key for Veeam Backup for Microsoft Office 365

Veeam is happy to provide a free NFR license (for 1 year, up to 10 users). This license allows for the non‑production use of Veeam Backup for Microsoft Office 365 in your home lab without any feature limitations.

 
LVL 29

Expert Comment

by:Olaf Doschke
ID: 41771461
Sorry, yes, wrong promise. It's 2012+ only.

Bye, Olaf.
0
 
LVL 3

Author Comment

by:John Smith
ID: 41771464
Thanks for the responses. That is giving me null values for some reason.
0
 
LVL 50

Expert Comment

by:Vitor Montalvão
ID: 41771465
I think the requirement need clarifications:
  • What's happening if you have two Johns or Tracys?
  • And if you want to select Anne (first record) or Tracy (last record)?
0
 
LVL 3

Author Comment

by:John Smith
ID: 41771469
Thanks for the response Vitor. I'm selecting the record by GUID, but want to include the previous / next records based on the Firstname, Surname values.
0
 
LVL 29

Expert Comment

by:Olaf Doschke
ID: 41771473
Well, LEAD and LAG only give one sclara value (expression), usually one column of the previous or next row, not the full previous/next row. So you get the next and previous lastname in two extra columns, not as separate rows.

You could query the guids you need to query:
select GUID,
       lag(guid) over (order by FirstName, SurName) PrevGUID,
	   lead(guid) over (order by FirstName, SurName) NxtGUID
  from your_table WHERE GUID = '...'

Open in new window


Bye, Olaf.
0
 
LVL 50

Expert Comment

by:Vitor Montalvão
ID: 41771474
I understand you're selecting by GUID but you're getting the previous and next records based in the firstname order and not in the GUID.
Like, Tracy's GUID is not the next one after Kevin's (it should by Geoff's by your example).
0
 
LVL 41

Expert Comment

by:Sharath
ID: 41771475
>> That is giving me null values for some reason.
post some sample data where you are getting NULLs.
0
 
LVL 29

Expert Comment

by:Olaf Doschke
ID: 41771484
You get NULLS because the main query only fetches one row, you can only get next and previous rows, if the result has more than the one row, that's the problem here.

This is going round in circles, if you first don't know the next and previous neighbors you have to row_number all and then you might also fetch all anyway, and scroll to the one guid.

Bye, Olaf.
0
 
LVL 29

Accepted Solution

by:
Olaf Doschke earned 500 total points
ID: 41771497
A straight forward approach would be along the lines of this

with cte as(
Select * from sys.objects so where so.object_id=5)

Select Top 1 so.* From sys.objects so cross apply cte where so.object_id<cte.object_id
union
Select * From cte
union
Select Top 1 so.* From sys.objects so cross apply cte where so.object_id>cte.object_id
order by object_id

Open in new window


Bye, Olaf.

Edit: Actually would need something alike:

Select * From (Select Top 1 * From sys.objects where object_id<5 order by object_id desc) t1
union all
(Select                     * From sys.objects where object_id=5)
union all
Select * From (Select Top 1 * From sys.objects where object_id>5 order by object_id asc) t2

Open in new window

0
 
LVL 3

Author Comment

by:John Smith
ID: 41771693
I'll try that and revert.
0
 
LVL 50

Expert Comment

by:Vitor Montalvão
ID: 41791325
John, any update of this question?
0
 
LVL 28

Expert Comment

by:Pawan Kumar
ID: 41821466
Hey John, Just wanted to check, have you checked code/post i mentioned.?
0

Featured Post

Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to reset the password of the sa account on a Microsoft SQL Server.  The steps in this article work in SQL 2005, 2008, 2008 R2, 2012, 2014 and 2016.
In this article we will learn how to fix  “Cannot install SQL Server 2014 Service Pack 2: Unable to install windows installer msi file” error ?
Familiarize people with the process of utilizing SQL Server functions from within Microsoft Access. Microsoft Access is a very powerful client/server development tool. One of the SQL Server objects that you can interact with from within Microsoft Ac…
This videos aims to give the viewer a basic demonstration of how a user can query current session information by using the SYS_CONTEXT function

751 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question