ďťż
 
 
   SQL - problem z zapytaniem do bazy
 
 

Tematy

 
    
 

 

 

 

SQL - problem z zapytaniem do bazy





gummmibear - 15-10-2009 18:12
Chciałbym wyciągnąć wszystkie aktywne umowy.
Na tabele z umowami składa się:
    l-id
    -id_klienta
    -id_projektu
    -data_rozpoczęcia
    -data_zakonczenial
Teraz jeżeli mamy taką tabelę: |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: 4 | 1 | 46 | 2009-08-24 | 2010-09-12 |

5 | 1 | 75 | 2009-08-24 | 2010-09-12 |



jaqbeu - 15-10-2009 18:41
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.



gummmibear - 15-10-2009 19:08
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

|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ć

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ąć ;[



ziecio - 16-10-2009 00:08
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:
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)



Ister - 16-10-2009 09:17
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:

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:

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.
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • minister.pev.pl

  •  

     


     

     
    Copyright 2003. MĂłj serwis