2009-10-18 7 views
1

J'ai deux tables MySQL, $ database1 et $ database2. Les deux ont un champ appelé ID. Je passe le nom d'une ville au fichier en utilisant GET (c'est-à-dire dans l'URL du fichier PHP qui contient ce code).Problèmes d'utilisation de GROUP BY dans MySQL dans une requête qui effectue une jointure sur deux tables

Je peux exécuter cette requête ...

$PlaceName = $_GET['townName']; 
$PlaceName = mysql_real_escape_string($PlaceName); 

$sql="SELECT * from $database1 LEFT JOIN $database2 on $database1.ID = $database2.ID WHERE PlaceName='$PlaceName'"; 
$query = mysql_query($sql); 

echo '<h1>People who are searching for '.$PlaceName.':</h1>'; 
echo '<ul>'; 
while ($row = mysql_fetch_array($query)) { 
    echo "<li>ID #",$row['ID'],": ",$row['MemberPersonalName']," ",$row['MemberSurname']," -- searching for ",$row['SurnameBeingSearched'],"</li>"; 
    } 
echo '</ul>'; 

... et ça marche et tout va bien. En ce moment, la sortie ressemble à ceci ...

Les gens qui sont à la recherche de Poudlard:

  • ID # 137: Hermione Granger - la recherche de Stern
  • ID # 137: Hermione Granger - la recherche d'Engelberg
  • ID # 503: Harry Potter - la recherche de Kreindler
  • ID # 549: Ron Weasley - la recherche de Kreindler
  • ID # 1062: Draco Malfoy - la recherche d'Engelberg
  • ID # 1155: Ginny Weasley - la recherche de Kreindler
  • ID # 1155: Ginny Weasley - la recherche de Streisand

Mais les besoins de sortie peaufiner, et j'ai du mal à écrire mon instruction de requête SQL pour refléter les changements. Ce que je veux vraiment est pour la sortie de ressembler à ceci ...

Les gens qui sont à la recherche de Poudlard:

  • Engelberg est recherché par Hermione Granger (id # 137) et Draco Malfoy (id # 1062)
  • Kreindler est recherché par Harry Potter (id # 503), Ron Weasley (id # 549), et Ginny Weasley (id # 1155)
  • Stern est recherché par Hermione Granger (id # 137)
  • Stre Isand est recherché par Ginny Weasley (id # 1155)

En d'autres termes, je dois groupe la production, ainsi que par le champ « SurnameBeingSearched », je dois énumérer les noms des personnes qui font la recherche dans un Format de sortie "X, Y, et Z" (où il sait où ajouter une virgule, si nécessaire, en fonction du nombre de résultats), et j'ai besoin de classer les résultats par le champ 'NameBeingSearched'.

Aide? Merci!

Répondre

2

Vous devez lister les noms afin qu'il ne s'agisse pas d'un problème d'agrégation (au sens SQL). Conservez votre requête actuelle Vous allez devoir faire le regroupement dans le code.

donc quelque chose comme:

$rows = array(); 
$last = ''; 
while ($row = mysql_fetch_array($query)) { 
    $surname = $row['SurnameBeingSearched']; 
    $id = $row['ID']; 
    $name = $row['MemberPersonalName']; 
    if ($last != $surname) { 
    $last = $surname; 
    $rows[] = array(); 
    } 
    $rows[count($rows)-1][$id] = $name; 
} 
foreach ($rows as $row) { 
    // now display each group of names 
} 
1

Vous pourriez également être en mesure d'utiliser la fonction MySQL GROUP_CONCAT().

Il ressemblerait à ceci ...

SELECT places_tbl.name, GROUP_CONCAT(people_tbl.name) 
FROM places_tbl 
LEFT JOIN people_tbl ON (places_tbl.id = people_tbl.id) 
GROUP BY places_tbl.id 

GROUP_CONCAT() par défaut retourne les valeurs délimité par des virgules. Vous pouvez probablement les séparer pour obtenir le formatage dont vous avez besoin ou utiliser le mot-clé SEPARATOR. GROUP_CONCAT(fieldname SEPARATOR '-')

+0

Je pense que le GROUP_CONCAT devrait être utilisé sur people_tbl.name il retournera « hémione Granger, Draco Malfoy » et GROUP BY places_tbl.name – andho

+0

Vous avez raison, j'ai mal lu la sortie désirée. Bonne prise! –

0
$PlaceName = $_GET['townName']; 
$PlaceName = mysql_real_escape_string($PlaceName); 

// note - added order to the query 
$sql="SELECT * from $database1 LEFT JOIN $database2 on $database1.ID = $database2.ID WHERE PlaceName='$PlaceName' 
     ORDER BY SurnameBeingSearched, MemberSurname, MemberPersonalName"; 
$query = mysql_query($sql); 

echo '<h1>People who are searching for '.$PlaceName.':</h1>'; 
echo '<ul>'; 
    $cntr = mysql_num_rows($query); 
    if ($cntr > 0) { 
    $i = 0; 
    $srchd = mysql_result($query, $i, 'SurnameBeingSearched');  
    $mbr = mysql_result($query, $i, 'MemberPersonalName'); 
    $mbr = $mbr . " " . mysql_result($query, $i, 'MemberSurname');  
    $mbr = $mbr . " (id #" . mysql_result($query, $i, 'ID') . ")";  
    $lin = $srchd . " is being searched by " . $mbr; 
    $prev = $srchd; 
    if ($cntr == 1) { 
     echo "<li>" . $lin . "</li>";    
    } else { 
     for ($i = 1; $i< $cntr; $i++) {   
     $srchd = mysql_result($query, $i, 'SurnameBeingSearched');  
     $mbr = mysql_result($query, $i, 'MemberPersonalName'); 
     $mbr = $mbr . " " . mysql_result($query, $i, 'MemberSurname');  
     $mbr = $mbr . " (id #" . mysql_result($query, $i, 'ID') . ")";  
     if ($srchd == $prev) { // common search 
      $j = $i + 1; 
      if ($j < $cntr) { // still have data 
      $nxt = mysql_result($query, $j, 'SurnameBeingSearched');  
      if ($prev == $nxt) { // another one coming -- use the comma 
       $lin = $lin . ", " . $mbr; 
      } else { 
       $lin = $lin . ", and " . $mbr; // last member add the 'and' - line is done 
       echo "<li>" . $lin . "</li>"; 
      }   
      $prev = $srchd; 
      } else { // ran out of data - need to finish the line 
      $lin = $lin . ", and " . $mbr; // last member add the 'and' - line is done 
      echo "<li>" . $lin . "</li>"; 
     } else { // new search - need to print this line and start a new one 
      echo "<li>" . $lin . "</li>";    
      $lin = $srchd . " is being searched by " . $mbr; 
      $prev = $srchd; 
     } // test searched = previous 
     } // next i 
    } // only one row 
    } // cntr > 0 
echo '</ul>'; 

/* note: this is not tested 
    I would recommend using table1 and table2 instead of database1 and database2 
    or better give the tables meaningful names 
    I would use active voice instead of passive voice 
*/ 
Questions connexes