2015-04-06 13 views
8

ho una tabella mysql di commenti, come questa.Mysql Come posso recuperare 2 set di risultati in una singola query dalla stessa tabella?

+------------+------------------+------+-----+---------+----------------+ 
| Field  | Type    | Null | Key | Default | Extra   | 
+------------+------------------+------+-----+---------+----------------+ 
| userid  | int(11)   | NO |  | 0  |    | 
| comment | char(255)  | NO |  | NULL |    | 
| content | int(11)   | NO | MUL | 0  |    | 
| ratings | int(11)   | NO |  | 0  |    | 
| datetime | datetime   | NO |  | NULL |    | 
| ip   | int(10) unsigned | NO |  | NULL |    | 
| is_updated | tinyint(2)  | NO |  | 0  |    | 
| record_num | int(11)   | NO | PRI | NULL | auto_increment | 
+------------+------------------+------+-----+---------+----------------+ 

ora posso recuperare i commenti da questo e i nomi utente da un'altra tabella utilizzando la query INNER JOIN come questa.

posso ottenere top 3 commenti ORDER BY DESC comments.ratings

SELECT comments.userid, users.username, comments.comment, comments.ratings, comments.datetime, comments.record_num , content.uploader , content.anonymous 
FROM comments 
LEFT JOIN users ON comments.userid = users.record_num 
LEFT JOIN content ON comments.content = content.record_num 
WHERE comments.content = ? ORDER BY comments.ratings DESC limit 3 

e

ottenendo regolare commenti ORDER BY comments.datetime DESC.

SELECT comments.userid, users.username, comments.comment, comments.ratings, comments.datetime, comments.record_num , content.uploader , content.anonymous 
FROM comments 
LEFT JOIN users ON comments.userid = users.record_num 
LEFT JOIN content ON comments.content = content.record_num 
WHERE comments.content = ? ORDER BY comments.datetime DESC limit ?, ? 

quello che sono tryingf a fare è mostrare agli utenti i primi 3 commenti per le loro valutazioni in un primo momento e poi regolare ordine commenti da comments.datetime DESC.

ora come posso unirmi sopra due query mysql in una?

risposta

9

Come l'altra risposta dice - è possibile combinare i risultati usando union - che significa semplicemente per unire due risultati insieme. Ciò che è importante notare, tuttavia, è che non puoi semplicemente fare queste due query direttamente, poiché usano order by, quindi dobbiamo racchiuderle nelle query esterne e usare una variabile di ranking per assicurarci di poter ricostruire l'unione in l'ordine che vogliamo:

select * from (
    SELECT 1 as tbl, 
      comments.userid, 
      users.username, 
      comments.comment, 
      comments.ratings, 
      comments.datetime, 
      comments.record_num, 
      content.uploader, 
      content.anonymous, 
      @rank := @rank + 1 as rank 
    FROM comments 
     LEFT JOIN users ON comments.userid = users.record_num 
     LEFT JOIN content ON comments.content = content.record_num 
     CROSS JOIN (select @rank := 0) q 
    WHERE comments.content = ? ORDER BY comments.ratings DESC limit 3 
) q1  
UNION ALL 
select * from ( 
    SELECT 2 as tbl, 
      comments.userid, 
      users.username, 
      comments.comment, 
      comments.ratings, 
      comments.datetime, 
      comments.record_num, 
      content.uploader, 
      content.anonymous, 
      @rank := @rank + 1 as rank 
    FROM comments 
     LEFT JOIN users ON comments.userid = users.record_num 
     LEFT JOIN content ON comments.content = content.record_num 
     CROSS JOIN (select @rank := 0) q 
    WHERE comments.content = ? ORDER BY comments.datetime DESC limit ?, ? 
) q2 
ORDER BY tbl asc, rank asc; 

union di default è distinct il che significa che non duplicare le righe si trovano in entrambi i set di risultati, tuttavia non v'è alcuna garanzia che anche le righe saranno restituite nell'ordine che ci si aspetta, da qui la necessità di contrassegnare ogni tabella con il proprio valore tbl e quindi il campo order by.

Se tu fossi certo non ci sarebbero duplicati, si potrebbe eliminare l'assegno duplicato utilizzando union all, invece di union

+0

grazie per il tuo input, che è una grossa query, – AMB

+0

@AMB sono le tue due domande - ho appena formattato in modo diverso per una lettura leggermente più semplice. Non c'è molto altro lavoro addizionale –

+0

c'è un modo, posso anche visualizzare anche valori duplicati, voglio dire se ci sono solo 3 commenti, quindi dovrebbe restituire 6 commenti, prima impostare l'ordine da commenti.ratings DESC e un altro set ORDER BY comments.datetime DESC – AMB

1

Per rispondere alla tua domanda, sì è possibile combinare le vostre domande utilizzando UNIONma

quello che sto cercando di fare è di mostrare agli utenti le migliori 3 commenti da parte dei loro feedback in un primo momento e poi ordinare i commenti regolare di comments.datetime DESC

Se il vostro stanno cercando di raggiungere qualcosa di simile alla funzionalità dei commenti di StackOverflow, dove i commenti superiore (o commenti con upvotes) sono mostrati prima, allora penso query separate è sufficientebuona.

Se la query è combinata, l'utente è tenuto a caricare tutti i commenti principali e regolari.Inoltre, è in qualche modo difficile fare o implementare un'impaginazione con grande query che hanno UNION (in base alla mia esperienza, perché im ancora un niubbo sulla codifica)

Disclamer: difficile, ma non impossibile

Se sono quello che codificherà quel problema, prima il mio programma caricherà i primi 3 commenti, dopo di che, c'è un pulsante 'Mostra più commenti' che posterò sul mio server usando AJAX e aggiungerò il risultato (commenti regolari) alla lista dei commenti mostrati. Con questo, le query devono essere separate come quello che hai ora

Problemi correlati