Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Złożony warunek dla dwóch DATETIME
ktuvok
post
Post #1





Grupa: Zarejestrowani
Postów: 243
Pomógł: 0
Dołączył: 30.11.2003

Ostrzeżenie: (0%)
-----


W tabeli "Zdarzenia" mam dwa pola typu DATETIME: DataB i DataC.

Jest następująca reguła:
- jeśli DataB jest przed godziną 13:00, to DataC musi być datą z tego samego
dnia,
- jeśli DataB jest po 13:00, to:
- jeśli DataB jest piątkowa, to DataC musi być datą z najbliższego
poniedziałku do godziny 12:00 (szerzej - najbliższego dnia roboczego, ale
nie będę się czepiał...),
- w przeciwnym wypadku DataC musi być datą z dnia następnego w stosunku
do DataB, do godziny 12:00.

Jak wybrać wszystkie zdarzenia zapisane w bazie, nie spełniające tej reguły?

MySQL 4.0.18 (brak podselectów).

Pozdrawiam,
Krzysiek
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 3)
popbart
post
Post #2





Grupa: Zarejestrowani
Postów: 255
Pomógł: 0
Dołączył: 22.04.2004
Skąd: Żoliborz

Ostrzeżenie: (0%)
-----


  1. SELECT pole1, IF(time(DataB)<'13:00:00' AND date(DataB)=date(DataC),'true',
  2. IF(time(DataB)>'13:00:00' AND dayname(DataB)='Friday' AND dayname(DataC)='Monday' AND time(DataC)<'12:00:00','true',
  3. IF(time(DataB)>'13:00:00' AND dayname(DataB)!='Friday' AND date(DataC)=date(DataB) + interval 1 day AND time(DataC)<12:00,'true','false'))
  4. AS warunek FROM tabela WHERE warunek='false'


Pozdrawiam,
Bartek

Ten post edytował popbart 12.11.2004, 23:13:11


--------------------
Visual Basic - kto by pomyślał :)
Go to the top of the page
+Quote Post
ktuvok
post
Post #3





Grupa: Zarejestrowani
Postów: 243
Pomógł: 0
Dołączył: 30.11.2003

Ostrzeżenie: (0%)
-----


Dzięki za zainteresowanie, to dosyć ciekawe rozwiązanie...

Ale w MySQL nie ma funkcji TIME ani DATE. Można je zamienić odpowiednio HOUR i DATE_FORMAT, co zresztą uczyniłem. Nie da się również w klauzuli WHERE użyć aliasu "warunek"; jedyne co mi przyszło do głowy to zamiana WHERE na HAVING.

Wyszło mi coś takiego:
  1. SELECT IDRekordu,
  2. IF(
  3. HOUR(DataB)<'13' AND DATE_FORMAT(DataB,'%Y-%m-%d')=DATE_FORMAT(DataC,'%Y-%m-%d'),'true',
  4. IF(
  5. HOUR(DataB)>'13' AND DAYNAME(DataB)='Friday' AND DAYNAME(DataC)='Monday' AND HOUR(DataC)<'12','true',
  6. IF(
  7. HOUR(DataB)>'13' AND DAYNAME(DataB)!='Friday' AND DATE_FORMAT(DataC,'%Y-%m-%d')=DATE_FORMAT(DataB,'%Y-%m-%d') + INTERVAL 1 DAY AND HOUR(DataC)<'12','true','false'
  8. )
  9. )
  10. )
  11. AS warunek FROM Zdarzenia HAVING warunek='false'


Tyle że to zapytanie jest skrajnie nieoptymalne - skanuje całą tabelę i nie wiedzieć czemu nie korzysta z indeksów, chociaż są wszędzie, gdzie być powinny. Zapewne to wina użycia HAVING zamiast WHERE.

Poza tym jeśli chcę dodać kolejny warunek, np. wybór zdarzeń od ... do ..., to muszę umieścić kolejnego IF'a zamiast prostego WHERE DataB BETWEEN ... AND ... , prawda?

Reasumując - nie da się jakoś prościej?

Pozdrawiam,
Krzysiek
Go to the top of the page
+Quote Post
popbart
post
Post #4





Grupa: Zarejestrowani
Postów: 255
Pomógł: 0
Dołączył: 22.04.2004
Skąd: Żoliborz

Ostrzeżenie: (0%)
-----


Co do time i date to zapomniałem dodać że są one dostępne dopiero od wersji 4.1.1.
Z tym having masz rację.
Warunek where możesz spokojnie wstawić przed klauzulą having i tam dawać jakieś inne warunki typu between.
Cytat
Tyle że to zapytanie jest skrajnie nieoptymalne - skanuje całą tabelę i nie wiedzieć czemu nie korzysta z indeksów, chociaż są wszędzie, gdzie być powinny. Zapewne to wina użycia HAVING zamiast WHERE.

A masz ustawione indeksy na pola DataB i DataC ?


--------------------
Visual Basic - kto by pomyślał :)
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 19.08.2025 - 20:30