2016-02-05 5 views
7

Mam dwie tabele - Klient BankietoweMySQL dostać najbliższą przyszłość datę do określonej daty, od daty umieszczone w innej tabeli mając wspólny identyfikator

Client Table 
---------------------------- 
ID  NAME 
1  John 
2  Jigar 
3  Jiten 

---------------------------- 
Banquet Table 
---------------------------- 
ID  CLIENT_ID DATED  
1  1   2016.2.3 
2  2   2016.2.5 
3  2   2016.2.8 
4  3   2016.2.6 
5  1   2016.2.9 
6  2   2016.2.5 
7  2   2016.2.8 
8  3   2016.2.6 
9  1   2016.2.7 

---------------------------- 
:::::::::: **Required Result** 
---------------------------- 
ID  NAME   DATED 
2  Jigar   2016.2.5 
3  Jiten   2016.2.6 
1  John   2016.2.7 

Rezultatem być generowany jest taki, że

1. Date, który jest przyszłość najbliższa lub równa bieżącej daty, która jest dodatkowo związany z danym klientem powinno być filtrowane i uporządkowane w formacie podanym w Wymagane Res zą

CURDATE() w obecnym przypadku jest 5.2.2016

Błędy: Zapytanie logicznego 1

SELECT c.id, c.name, b.dated 
FROM client AS c, banquet AS b 
WHERE c.id = b.client_id AND b.dated >= CURDATE() 
ORDER BY (b.dated - CURDATE()); 

------------------------------------------- OUTPUT 
ID  NAME   DATED 
2  Jigar   2016.2.5 
2  Jigar   2016.2.5 
3  Jiten   2016.2.6 
3  Jiten   2016.2.6 
1  John   2016.2.7 
2  Jigar   2016.2.8 
2  Jigar   2016.2.8 
1  John   2016.2.9 

Błędy: logicznego Zapytanie 2

SELECT c.id, c.name, b.dated 
FROM client AS c, banquet AS b 
    WHERE b.dated = (
     SELECT MIN(b.dated) 
     FROM banquet as b 
     WHERE b.client_id = c.id 
      AND b.dated >= CURDATE() 
    ) 
ORDER BY (b.dated - CURDATE()); 

------------------------------------------- OUTPUT 
ID  NAME   DATED 
2  Jigar   2016.2.5 
2  Jigar   2016.2.5 
3  Jiten   2016.2.6 
3  Jiten   2016.2.6 
1  John   2016.2.7 

sqlfiddle

UPDATE Bliższe wynik być generowany w taki sposób,

2. klienta bez: Data należy wymienić również może być realizowane z pustym

3. informacje inne niż ZAWARTE w tabeli BANQUET również muszą być wymienione

AKTUALIZACJA wymaganego rezultatu

ID  NAME   DATED  MEAL 
2  Jigar   2016.2.5  lunch 
3  Jiten   2016.2.6  breakfast 
1  John   2016.2.7  dinner 
4  Junior  -   - 
5  Master  -   supper 
+0

skąd 'mączka' pochodzi? biorąc pod uwagę, że po udzieleniu odpowiedzi zmieniłeś pytanie w znacznym stopniu, możesz zadać osobne pytanie dotyczące spraw "NULL" i "posiłku". – Stidgeon

+0

@Stidgeon Byłem także zdezorientowany, że powinienem zapytać o to w tym samym pytaniu lub w nowym pytaniu. Ale teraz myślę, że nowe pytanie to dobry sposób .. – kanudo

Odpowiedz

2

dla tego zapytania, sugeruję zastosowanie kondycję >= CURDATE()WHERE a następnie SELECTMIN(dated) z GROUP BY client_id:

SELECT b.client_id, MIN(b.dated) FROM banquet b 
WHERE b.dated >= CURDATE() 
GROUP BY b.client_id; 

od tego, można dodać niezbędne JOIN do tabeli klienta, aby uzyskać c Nazwa lient:

SELECT b.client_id, c.name, MIN(b.dated) FROM banquet b 
INNER JOIN client c 
ON c.id = b.client_id 
WHERE b.dated >= CURDATE() 
GROUP BY b.client_id; 

SQLFiddle: http://sqlfiddle.com/#!9/aded8/18

EDITED aby odzwierciedlić nowe części pytania:

oparciu o nowe informacje dodanej - pytanie, jak obsługiwać wartości null i 'mączka' kolumnie I Wprowadziłem pewne zmiany. Ta zaktualizowana kwerenda obsługuje możliwe wartości null (zmieniając klauzulę WHERE) w dniu, a także zawiera informacje o posiłku.

SELECT b.client_id, c.name, 
MIN(b.dated) AS dated, 
IFNULL(b.meal, '-') AS meal 
FROM banquet b 
INNER JOIN client c 
ON c.id = b.client_id 
WHERE b.dated >= CURDATE() OR b.dated IS NULL 
GROUP BY b.client_id; 

lub możesz wziąć trochę tego i połączyć go z odpowiedzią Gordona Linoffa, która brzmi, jakby lepiej wypadła.

New SQLFiddle: http://sqlfiddle.com/#!9/a4055/2

+0

działa świetnie, a na tym jest również w stanie uzyskać dowolne pola z obu tabel, po prostu wspominając w "SELECT". Ale nie jest w stanie podać "KLIENTÓW" z 'BANQUET.DATED' havin' NULL'. To nie było moje pierwsze pytanie, ale poprawiłem i zaktualizowałem pytanie tak samo. – kanudo

1

Try To

SELECT banquet.client_id, MIN(banquet.dated) 
FROM banquet 
WHERE banquet.dated >= CURDATE() 
GROUP BY banquet.client_id; 

jeśli chcesz ograniczoną wyjścia jak twój oczekiwany wynik wynosi 3 zapis, dzięki czemu można używać limit w tym przypadku

SELECT banquet.client_id, MIN(banquet.dated) 
FROM banquet 
WHERE banquet.dated >= CURDATE() 
GROUP BY banquet.client_id limit 3; 

jeśli chcesz użyć join z tabelą Client, której możesz użyć `join '

SELECT banquet.client_id, MIN(banquet.dated) 
FROM banquet JOIN Client 
ON Client.id = banquet.client_id 
WHERE banquet.dated >= CURDATE() 
GROUP BY banquet.client_id; 

również użyć limit z ostatnim zapytaniem.

2

Jedno podejście wykorzystuje podzapytanie skorelowane:

select c.*, 
     (select max(dated) 
     from banquet b 
     where b.client_id = c.id and 
       b.dated >= CURDATE() 
     ) as dated 
from client c; 

Następnie Polecam indeks na banquet(client_id, dated).

Zaletą tego podejścia jest wydajność. Nie wymaga agregacji na całej tabeli klienta. W rzeczywistości skorelowane podzapytanie może skorzystać z indeksu, więc zapytanie powinno mieć dobrą wydajność.

+0

jego działanie jest niesamowite, gdy tylko 'banquet.dated' ma być traktowane jako wynik z' banquet'. Ale kiedy próbowałem dostać 'banquet.meal' również dla wyjścia, to nie działa. Cóż, to nie było moje pierwsze pytanie, ale zaktualizowałem pytanie tak samo. – kanudo

1

daty która jest najbliższa lub równa bieżącej daty

Aby ściśle rspond do swoich wymagań i. mi. "CLOSEST" może być zarówno przed lub po aktualną datę, zapytanie musi używać (bezwzględna) różnica między nim a wartością DATED.

więc można osiągnąć tak:

SELECT 
    c.id, c.name, b.dated, 
    MIN(ABS(TIMESTAMPDIFF(DAY, b.dated, CURDATE()))) AS `delta` 
FROM banquet AS b 
    INNER JOIN client AS c ON b.client_id = c.id 
GROUP BY b.client_id 

Oto SQL fiddle

+0

@Stidgeon Tak, teraz to widzę. Ale pytanie zostało zmodyfikowane, po prostu dodając "przyszłość" (patrz redakcja 1), prawdopodobnie gdy OP przeczytał moją odpowiedź i uświadomił sobie, że pytanie było niejednoznaczne. – cFreed

+0

ah. . . dzięki. Rozumiem, co masz na myśli. – Stidgeon

+0

@ cFreed również to nie było moje dokładne pytanie nadal pomógł mi w moim drugim zapytaniu stąd wznowione odpowiedź – kanudo