Strona 1 z 1
SQL - problem z zapytaniem do bazy
: 15 października 2009, 18:12
autor: gummmibear
Chciałbym wyciągnąć wszystkie aktywne umowy.
Na tabele z umowami składa się:
- -id
-id_klienta
-id_projektu
-data_rozpoczęcia
-data_zakonczenia
Teraz jeżeli mamy taką tabelę:
Kod: Zaznacz cały
|id| |id_klient| id_projekt | data_rozpoczecia | data_zakonczenia |
4 | 1 | 46 | 2009-08-24 | 2010-09-12 |
1 | 1 | 75 | 2009-03-09 | 2010-09-12 |
5 | 1 | 75 | 2009-08-24 | 2010-09-12 |
Wynikiem zapytania powinno być najświeższa umowa dla danego id_klienta i id_projektu. Czyli coś takiego:
Kod: Zaznacz cały
4 | 1 | 46 | 2009-08-24 | 2010-09-12 |
5 | 1 | 75 | 2009-08-24 | 2010-09-12 |
: 15 października 2009, 18:41
autor: jaqbeu
Kod: Zaznacz cały
SELECT * FROM tabelazumowa WHERE id_klienta=1 AND data_rozpoczecia=(SELECT MAX(data_rozpoczecia) FROM tabelazumowa);
W Twoim przykładzie nr. projektów są różne, ale w razie czego dodasz sobie jeszcze jedno AND i Ci wybierze co chcesz.
: 15 października 2009, 19:08
autor: gummmibear
jaqbeu
Chodzi mi o wyciągnięcie wszystkich aktywnych umów które znajdują się w bazie. I ich data rozpoczęcia jest <= daty dzisiejszej. Jeżeli mamy dwie podpisane umowy dla tego samego klienta i projektu wybieramy tą z późniejszą datą.
W przypadku
Kod: Zaznacz cały
|id| |id_klient| id_projekt | data_rozpoczecia | data_zakonczenia |
14| 12 | 36 | 2009-05-24 | 2010-09-12 |
4 | 12 | 36 | 2009-08-24 | 2010-09-12 |
1 | 1 | 75 | 2009-03-09 | 2010-09-12 |
5 | 1 | 75 | 2009-08-24 | 2010-09-12 |
6 | 4 | 46 | 2009-08-24 | 2010-09-12 |
7 | 13 | 25 | 2009-03-09 | 2010-09-12 |
Wynikiem zapytania powinno być
Kod: Zaznacz cały
4 | 12 | 36 | 2009-08-24 | 2010-09-12 |
5 | 1 | 75 | 2009-08-24 | 2010-09-12 |
6 | 4 | 46 | 2009-08-24 | 2010-09-12 |
7 | 13 | 25 | 2009-03-09 | 2010-09-12 |
Jakoś nie mogę tego zapytania ogarnąć ;[
: 16 października 2009, 00:08
autor: ziecio
Normalnie tak mnie tym zadaniem zaciekawiłeś, że spędziłem ponad 1,5h żeby to rozgryźć, niestety nie dałem rady i z determinacji znalazłem na google. A rozwiązanie jest takie:
Kod: Zaznacz cały
SELECT * FROM umowy INNER JOIN(SELECT max(`data_rozpoczecia`) as MaxDate, `id_klienta` FROM umowy GROUP BY `id_klienta`) as g ON (umowy.`id_klienta`=g.`id_klienta`) AND (umowy.`data_rozpoczecia`=g.MaxDate)
: 16 października 2009, 09:17
autor: Ister
Odpowiedź jest niepełna - nie uwzględnia sytuacji, w której jeden klient ma umowę na kilka projektów. Nie uwzględnia też umów już zakończonych i jeszcze nie rozpoczętych. Ja bym to uzupełnił tak:
Kod: Zaznacz cały
SELECT u.*
FROM umowy AS u
INNER JOIN
(
SELECT max('data_rozpoczecia') AS MaxDate, 'id_klient', 'id_projekt'
FROM umowy
WHERE now() BETWEEN 'data_rozpoczecia' AND 'data_zakonczenia'
GROUP BY 'id_klient','id_projekt'
) AS g ON (u.'id_klient'=g.'id_klient')
AND (u.'id_projekt'=g.'id_projekt')
AND (u.'data_rozpoczecia'=g.MaxDate)
a żeby nie było, że tylko z gotowych rozwiązań korzystam, to wcześniej pokombinowałem i wyprodukowałem coś takiego, podejrzewam, że wydajnościowo słabsze, ale też powinno zadziałać (dla wygody pomijam wszystkie 'uszy' w nazwach tabel i kolumn:
Kod: Zaznacz cały
SELECT *
FROM umowy
WHERE now() BETWEEN data_rozpoczecia AND data_zakonczenia
AND id NOT IN
(
SELECT u1.id
FROM umowy u1
JOIN umowy u2 ON u1.id_klient=u2.id_klient
AND u1.id_projekt=u2.id_projekt
AND u1.data_zakonczenia<u2.data_zakonczenia
WHERE now() BETWEEN u1.data_rozpoczecia AND u1.data_zakonczenia
AND now() BETWEEN u2.data_rozpoczecia AND u2.data_zakonczenia
)
Cóż, wymyślenie tego rozwiązania zajęło mi nie więcej niż pół godziny...
[ Dodano: 2009-10-16, 09:19 ]
Jeszcze jedno - nie napisałeś w jakiej bazie danych jesteśmy. Oba powyższe rozwiązania działać powinny w każdej bazie SQLowej. Natomiast w Oracle'u można napisać eleganckie zapytanie zagnieżdżone. Przynajmniej tak mi się wydaje, bo szczerze mówiąc nie chce mi się dokładnie rozpisywać trzeciej już wersji.