2016-02-05 9 views
7

Ho due tavoli - Cliente e banchettiMySQL ottenere la data prossimo futuro per certa data, a partire dalle date situati in tabella diversa avendo ID comune

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 

Il risultato deve essere generato è tale che

1. la data, cioè FUTURO: il più vicino o uguale alla data corrente, che è ulteriormente legato al rispettivo cliente dovrebbe essere filtrati e ordinati in formato indicato negli richiesto Res ult

CURDATE() per il caso attuale è 5.2.2016

FAILED: Query Logic 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 

FAILED: Logic Query 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 arg risultato da generare è tale che

2. clienti senza: DATATE dovrebbe anche essere elencati: può essere con un NULL

3. anche le informazioni diverse da DATED nella tabella BANQUET devono essere elencate

AGGIORNATO Risultato Richiesto

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

da dove viene 'pasto' viene? dato che hai cambiato la tua domanda in modo significativo dopo aver ricevuto una risposta, potresti voler inserire una domanda separata per i casi "NULL" e "pasto". – Stidgeon

+0

@Stidgeon Sono stato anche confuso che dovrei chiedere questo nella stessa domanda o in una nuova domanda. Ma ora penso che la nuova domanda sia un buon modo .. – kanudo

risposta

2

Per questa query, vi suggerisco di applicare il WHERE condizioni >= CURDATE() e poi SELECT la MIN(dated) con GROUP BY client_id:

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

Da questo, è possibile aggiungere il necessario JOIN alla tabella client per ottenere il c Nome UIDA DI RIFERIMENTO:

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

modificati per riflettere le nuove PARTI DI DOMANDA:

Sulla base del nuovo informazioni si è aggiunto - chiedendo come gestire i null e la colonna 'pasto', io ho apportato alcune modifiche. Questa query aggiornata gestisce eventuali valori nulli (modificando la clausola WHERE) in datato e include anche informazioni sui pasti.

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; 

oppure si può prendere un po 'di questo e combinarlo con la risposta di Gordon Linoff, che suona come esso deve svolgere meglio in generale.

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

+0

funziona alla grande, e su questo è anche in grado di ottenere qualsiasi campo da entrambe le tabelle semplicemente menzionando in 'SELECT'. Ma non è in grado di fornire 'CLIENT' con' BANQUET.DATED' havin 'NULL'. Beh, non era la mia domanda iniziale, ma ho migliorato e aggiornato la domanda per lo stesso. – kanudo

1

Try This

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

se si desidera uscita limitata come il vostro risultato atteso è di 3 record di modo da poter utilizzare limit in questo caso

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

se vuoi utilizzare il join con la tabella Client puoi usare `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; 

utilizzare anche limit con l'ultima richiesta.

2

Un approccio utilizza una subquery correlata:

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

Poi, mi sento di raccomandare un indice su banquet(client_id, dated).

Il vantaggio di questo approccio è le prestazioni. Non richiede un'aggregazione sull'intera tabella client. In effetti, la sottoquery correlata può sfruttare l'indice, quindi la query dovrebbe avere buone prestazioni.

+0

funziona perfettamente quando solo 'banquet.dated' deve essere preso come output da' banquet'. Ma quando ho provato a ottenere 'banquet.meal' anche per l'output non funziona. Beh, non era la mia domanda iniziale, ma ho aggiornato la domanda per lo stesso. – kanudo

1

La data che è più vicina o uguale alla data corrente

Per strettamente rspond alle vostre esigenze, i. e. "CLOSEST" può essere sia sia prima che dopo la data corrente, la query deve utilizzare la differenza (assoluta) tra esso e il valore DATED.

in modo che possa essere raggiunto in questo modo:

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 

Ecco la SQL fiddle

+0

@Stidgeon Sì, ora lo vedo. Ma la domanda è stata modificata, aggiungendo semplicemente "futuro" (guarda modifica 1), probabilmente quando l'OP ha letto la mia risposta e ha capito che la domanda era ambigua. – cFreed

+0

ah. . . Grazie. Capisco cosa intendi. – Stidgeon

+0

@cFreed anche questa non era la mia domanda esatta ancora mi ha aiutato per la mia altra query da allora ha alzato la risposta – kanudo