[MSSQL] Select i następny rerkord

[MSSQL] Select i następny rerkord
JU
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 5046
0

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

Kopiuj
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ąć.

JU
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 5046
0

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

Uproszczony schemat:

Kopiuj
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:

Kopiuj
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:

Kopiuj
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)

  • Rejestracja: dni
  • Ostatnio: dni
0

a sprobuj

Kopiuj
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
AP
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3079
0

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

Wystarczyło zrobić tabelkę

Kopiuj
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.

JU
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 5046
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ę

Kopiuj
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.

AP
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3079
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.

crowa
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Poznań
  • Postów: 295
0

a nie mozna tak

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

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.