webForumDet fria alternativet

Hur ska man hanskas med LEFT JOIN?

PHPur PHP

7 svar · 604 visningar · startad av Hamatzu

Medlem sedan mars 2005232 inlägg
Frågan#1

Hej!
Har en tabell med namn på olika tjänster och en tabell med olika varianter av denna tjänst. Jag vill ha ut namnet på tjänsten och dess tillhörande varianter efter varann.

Har följande sql-fråga:

SELECT service.*, service_info.* FROM service LEFT JOIN service_info ON service.service_id = service_info.service_id WHERE service.cal_id=".$cal_id." ORDER BY service.service_id DESC

Sedan så loopar jag ut det på följande sätt:

while($r = mysql_fetch_assoc($calRes))
				{

					$service_name = $r['name'];
					$time = $r['time_consumption'];
					
					echo $service_name."
							<br />
                          ".$time;
					
				}

Blir följande:

Test1
30
Test1
60
Test1
90
Test2
30
Test3
30
Test3
60

Jag vill ha detta resultat:

Test1
30
60
90
Test2
30
Test3
30
60
Medlem sedan juni 20006 031 inlägg
#2

Jag är ingen SQL stjärna, men bör du inte använda GROUP BY?

Flyttar även tråden från PHP.

Medlem sedan mars 2005232 inlägg
#3

Har testat det, men då får jag bara ut följande resultat:

Test1
30
Test2
30
Test3
30
Medlem sedan juni 200032 967 inlägg
#4

Jag tänker flytta tillbaka till PHP - eftersom presentationen ska lösas där, inte i SQL.

Du får sätta en kontrollvariabel i php för att hålla koll på den senaste servicename du skrivit ut. Är servicename samma i den här iterationen, skriv inte ut det, skriv bara ut tiden. Är servicename ett annat, skriv ut det och sätt om kontrollvariabeln för senaste servicename.

Medlem sedan aug. 20039 340 inlägg
#5

Finns två sätt att lösa det. Antingen med PHP, och då skriver du bara ut servicenamnet om det är förändrat sen förra rundan.

                $service_name = '';

                while($r = mysql_fetch_assoc($calRes))
                {

                    $time = $r['time_consumption'];
                    if($service_name != $r['name']){
                        $service_name = $r['name'];
                        echo $service_name."<br />\n";
                    }

                    echo $time."<br />\n";
                }

Du kan även använda GROUP BY och CONCAT_WS.

SELECT service.*, service_info.*, GROUP_CONCAT(service_info.time_consumption SEPARATOR ',') AS time_consumption_c
  FROM service 
LEFT JOIN service_info ON service.service_id = service_info.service_id
 WHERE service.cal_id=".$cal_id."
GROUP BY service.service_id
ORDER BY service.service_id DESC

GROUP BY grupperar ihop alla rader med samma service_id till en rad. concat_ws är en aggregatfunktion, ungefär som sum, som gör något med ihopgcupperade rader. Just concat_ws fogar samman alla raderna till en lång sträng. I detta fall har jag angivit att strängarna ska separeras med ett komma.

                while($r = mysql_fetch_assoc($calRes))
                {

                    $service_name = $r['name'];
                    $time = $r['time_consumption'];
                    
                    echo $service_name."<br />\n";
                    $time_array = explode(",", $time);
                    echo implode("<br />\n", $time_array) . "<br />\n";
                }

PHP-koden delar i sin tur upp denna sträng efter komman. Då får man en array. Denna array pusslas sedan ihop med strängen "<br />\n" som klister.

Medlem sedan juni 200032 967 inlägg
#6

Kul SQL-lösning, nitro!

Det finns många klurigheter i MySQL - tydligen. :)
Jag kan dock ändå tycka att det bör lösas i php - eftersom man inte bör lösa presentationsproblem i SQL-frågor.

Medlem sedan aug. 20039 340 inlägg
#7

Snabel-anders: Strikt sett så har jag ju inte löst presentationsproblemet i SQL. Jag gör eventuellt datat lättare/mer logiskt att hantera, men det är inte nödvändigtvis samma sak som att det är presentationen manfixar. Jag fogar samman numren med en separator. Först i PHP bryr jag mig om presentationen efter att jag har delat upp strängen till en array. Hårklyveri kanske, men jag kunde ju lika gärna kört '<br />' som separator direkt. Dock blev det fel funktionsnamn i SQL-koden. Bäst att jag fixar det snabbt så att ingen får reda på att jag skrev fel.

Medlem sedan juni 200032 967 inlägg
#8

nitro2k01 skrev:

Snabel-anders: Strikt sett så har jag ju inte löst presentationsproblemet i SQL. Jag gör eventuellt datat lättare/mer logiskt att hantera, men det är inte nödvändigtvis samma sak som att det är presentationen manfixar.

Ayt! (y)

nitro2k01 skrev:

Bäst att jag fixar det snabbt så att ingen får reda på att jag skrev fel.

Ja. Så går det ju inte att ha det.

139 ms totalt · 3 externa anrop · v20260731065814-full.4bcf49fe
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
136 ms — hämta tråd, inlägg och bilagor (db)