Piotr Głudkowski

Piotr Głudkowski Rzucam się na
wszystko to, co jest
ciekawe i wymaga
rusze...

Temat: MSSQL: szybkie pytanie o selecta

Jest sobie tabela OrderStatus z trzema kolumnami:
ID_Order [varchar]
Status [int]
StatusDate [datetime]

Każdy order może mieć wiele statusów, czyli może być wiele wierszy dla każdego ID_Order. Ale dla każdego ID_Order dana wartość Status może wystąpić tylko raz.

Potrzebuję znaleźć takie ID_Order, które spełniają jednocześnie poniższe warunki:
- mają wiersz ze Status = 90
- mają wiersz ze Status = 85
- StatusDate dla statusu 90 jest wcześniejsze (mniejsze) od StatusDate dla statusu 85

Pomóżcie, proszę, bo muszę wyłapać zlecenia do poprawienia - puściłem buga w integracji (już poprawiłem) i się naknociło... Zanim klient zgłosił i znalazłem przyczynę poleciało kilka tysięcy knotów i teraz muszę to szybko odkręcić. Klient beczy a ja mam jakieś zaćmienie w kwestii SQL-a :(Piotr Głudkowski edytował(a) ten post dnia 31.03.11 o godzinie 01:40Piotr Głudkowski edytował(a) ten post dnia 31.03.11 o godzinie 01:41Piotr Głudkowski edytował(a) ten post dnia 31.03.11 o godzinie 01:47Piotr Głudkowski edytował(a) ten post dnia 31.03.11 o godzinie 02:07
Piotr Głudkowski

Piotr Głudkowski Rzucam się na
wszystko to, co jest
ciekawe i wymaga
rusze...

Temat: MSSQL: szybkie pytanie o selecta

Takie coś nie działa - nic nie zwraca :(


select s1.ID_Order
from OrderStatus s1, OrderStatus s2
where s1.ID_Order = s2.ID_Order
and s1.Status = 85
and s2.Status = 90
and s1.StatusDate > s2.StatusDate
Piotr Głudkowski

Piotr Głudkowski Rzucam się na
wszystko to, co jest
ciekawe i wymaga
rusze...

Temat: MSSQL: szybkie pytanie o selecta

Ok, już mam.
Zadziałało zagnieżdżenie:


select s1.ID_Order
from OrderStatus s1
where s1.Status = 85
and s1.ID_Order in ( select s2.ID_Order
from OrderStatus s2
where s2.Status = 90
and s1.StatusDate > s2.StatusDate )

konto usunięte

Temat: MSSQL: szybkie pytanie o selecta

Nie wiem jak mssql server sobie to rozbiera. Trzeba zobaczyć explain.
Ja bym raczej poszedł w joina. Coś w ten deseń:

select s1.ID_Order
from
OrderStatus s1
join OrderStatus s2 on
s1.ID_Order = s2.ID_Order and s1.StatusDate > s2.StatusDate
where
s1.Status = 85
and s2.Status = 90

Chodzi o to, że w ten sposób baza z automatu użyje statystyk do wyboru optymalnego powiązania. Jeżeli np. będzie parę statusów 90 a dużo 85 - wtedy zrobi merge joina w tą stronę. Jak odwrotnie - to odwrotnie. Przy subselect wcale nie jestem pewien, czy będzie taki sprytny. No, ale to trzeba sprawdzić explainem. Ciekaw jestem, jak to wygląda w praktyce.

Zupełnie inna sprawa, że zapis z joinem imvho jest prostszy.
Piotr Głudkowski:
Ok, już mam.
Zadziałało zagnieżdżenie:


select s1.ID_Order
from OrderStatus s1
where s1.Status = 85
and s1.ID_Order in ( select s2.ID_Order
from OrderStatus s2
where s2.Status = 90
and s1.StatusDate > s2.StatusDate )

Temat: MSSQL: szybkie pytanie o selecta

Jeśli masz MSSQL w wersji 2005 i nowszej możesz skorzystać z CTE.
server przetwarza to tak samo jak query z podzapytaniem, ale według mnie taki zapis jest o wiele bardziej czytelny

With
-- lista zamówień ze statusem 85
OrderStatus_85
AS
(
Select ID_Order
From OrderStatus
Where Status = 85
),
-- lista zamówień ze statusem 90
OrderStatus_90
AS
(
Select ID_Order
From OrderStatus
Where Status = 90
)
Select *
From OrderStatus_85 os85 join OrderStatus_90 os90
on os85.OrderID = os90.OrderID
Where os85.StatusDate > os90.StatusDateDawid Pierzchalski edytował(a) ten post dnia 10.05.11 o godzinie 09:07

Następna dyskusja:

mssql - pytanie o pary prod...




Wyślij zaproszenie do