[MSSQL] Select i następny rerkord

0

Cześć, załóżmy, że mam zapytanie:

select date, isOut
from tabela
order by date

I teraz pytanie jest takie, czy możliwe jest z poziomu selecta sprawdzenie wartości pola isOut, ale nie "aktualnego" rekordu, lecz następnego.
Wiem, że mógłbym do tego użyć kursora, ale chcę tego uniknąć.

0

Wpadłem na coś takiego, ale z jakiegoś powodu nie działa :|

Uproszczony schemat:

select employeeID, date, 
     (case when isOut = 0 then [time] else null end) as [in], 
     (case 
	when isOut = 0 and (select top 1 ve.isOut from V_Widok ve
			  where ve.employeeID = employeeID and 
		                    ve.date>date
			  order by date
			  ) = 1 
                    then (select top 1 ve.[time] from V_Widok ve
		  where ve.employeeID = employeeID and 
                            ve.date>date 
                            order by date)
	else
	(case when isOut = 1 then [time] else null end) end) as out
from V_Widok
order by employeeID, date, out, [in]

Efektem tego zapytania jest coś takiego:

1          2009-03-10          11:00          NULL
1          2009-03-10          NULL           11:30
1          2009-03-10          11:45          NULL
1          2009-03-10          NULL           15:00
1          2009-03-10          NULL           16:00

A ja walczę, żeby uzyskać coś takiego:

1          2009-03-10          11:00          11:30
1          2009-03-10          11:45          15:00
1          2009-03-10          NULL           16:00

No i wg mnie powyższe pytanie powinno działać. Ale nie działa :/

(jeśli chodzi o podzapytania to zwracają to, co powinny)

0

a sprobuj

select employeeID, date, 
     (case when isOut = 0 then [time] else null end) as [in], 
     (case 
        when isOut = 0 and (select top 1 ve.isOut from V_Widok ve
                          where ve.employeeID = employeeID and 
                                    ve.date>date
                          order by date
                          ) = 1 
                    then (select top 1 ve.[time] from V_Widok ve
                  where ve.employeeID = employeeID and 
                            ve.date>date 
                            order by date)
        else
        (case when isOut = 1 then [time] else null end) end) as out
from V_Widok
order by employeeID, date, 
case when out is null then 1  else 0 end, 
case whern [in] is null then 1 else 0 end
0

Nie mogłeś się nad tym zastanowić na poziomie projektowania struktury tabel?

Wystarczyło zrobić tabelkę

CREATE TABLE tab
(
  employeeId int,
  in datetime,
  out datetime
)

oraz procedurę, która w momencie wpisania loginu szuka w tab rekordu z niepustym in i pustym out, jeżeli znajdzie to out = getdate(), a jeżeli nie znajdzie to in = getdate() i miałbyś problem z głowy.

0
AdamPL napisał(a)

Nie mogłeś się nad tym zastanowić na poziomie projektowania struktury tabel?

Nie. Jak wiadomo, założenia aplikacji zmieniają się w czasie ;>

Wystarczyło zrobić tabelkę

CREATE TABLE tab
(
  employeeId int,
  in datetime,
  out datetime
)

oraz procedurę, która w momencie wpisania loginu szuka w tab rekordu z niepustym in i pustym out, jeżeli znajdzie to out = getdate(), a jeżeli nie znajdzie to in = getdate() i miałbyś problem z głowy.

To nie takie proste.
Ale już se jakoś poradziłem, za pomocą tgo kursora. Okazało się, że nie jest taki wolny.

0

Jeżeli w kursorze robisz jakąś prostą operację typu składanie selecta to nie jest zbyt obciążający. Jedynie wywoływanie procedur, funkcji dla każdego rekordu w kursorze to porażka.

0

a nie mozna tak

SELECT pole,
            (SELECT TOP 1 pole FROM tabela T1 WHERE T1.Id > T2.Id)
FROM tabela T2

1 użytkowników online, w tym zalogowanych: 0, gości: 1