Avatar billede neo-fisk Nybegynder
13. marts 2011 - 00:13 Der er 13 kommentarer og
1 løsning

Mysql Query (måske JOIN)

jeg sidder og arbejder lidt på en select som jeg gerne skulle have kogt ned til en enkelt pæn query der er nemmere at sortere på, jeg kunne forstille mig det er noget join jeg skal kigge på..

det jeg gerne vil opnå er at kunne lave en ORDER BY på category_name og manufactures_name

Jeg har følgende querys:

$varelinier = mysql_query ( "SELECT products_name, products_id, final_price, SUM(products_quantity) AS total_quantity FROM zen_orders_products WHERE orders_id IN ($final_ids) GROUP BY products_name" )or die(mysql_error());

while($varelinie = mysql_fetch_array($varelinier)) {
echo "<tr>";
echo "<td>" . $varelinie['products_id'] . "</td>";
echo "<td>" . $varelinie['products_name'] . "</td>";
echo "<td>" . $varelinie['total_quantity'] . "</td>";

$cat_id = mysql_query ( "select master_categories_id FROM zen_products WHERE products_id = $varelinie[products_id]" )or die(mysql_error());
$row20 = mysql_fetch_assoc($cat_id);
$par_id = mysql_query ( "select parent_id FROM zen_categories WHERE categories_id = $row20[master_categories_id]" )or die(mysql_error());
$row21 = mysql_fetch_assoc($par_id);
$cat_name = mysql_query ( "select categories_name FROM zen_categories_description WHERE categories_id = $row21[parent_id]" )or die(mysql_error());
$row22 = mysql_fetch_assoc($cat_name);
echo "<td>" . $row22['categories_name'] . "</td>";

$man_id = mysql_query ( "select manufacturers_id FROM zen_products WHERE products_id = $varelinie[products_id]" )or die(mysql_error());
$row10 = mysql_fetch_assoc($man_id);

$man_name = mysql_query ( "select manufacturers_name FROM zen_manufacturers WHERE manufacturers_id = $row10[manufacturers_id]" )or die(mysql_error());
$row11 = mysql_fetch_assoc($man_name);
echo "<td>" . $row11['manufacturers_name'] . "</td>";
echo "<td>" . $varelinie['total_quantity'] . $order_supplier . "</td>";

echo "</tr>";
Tak på forhånd
13. marts 2011 - 07:50 #1
neo-fisk, det var ikke nemt at udrede.  Og du bruger i den naest-sidste linie af koden en variabel $order_supplier som jeg ikke kan se du definerer.  Jeg har derfor vaeret noedt til at ignorere hele den linie.  Men for oevrigt forstaar jeg at du har seks tabeller der haenger sammen som vist her: http://christianjorgensen.be/Billeder/neofisk.gif (jeg har forkortet tabelnavnene lidt.) 

Og saa vil du for hver produkt vil have udskrevet id, navn, quantity, category, og manufacturer sorteret paa category og manufacturer.

Hvis jeg har fattet det rigtigt, isaer tabelstrukturen, saa bliver selve queryen denne:

SELECT o.orders_id, o.product_name, SUM(o.product_quantity) AS total_quantity, d.categories_name, m.manufacturers_name
FROM Orders_Products o JOIN Products p ON o.products_id = p.products_id JOIN Manufacturers m ON p.manufacturers_id = m.manufacturers_id JOIN Categories c ON p.master_categories_id = c.parent_id JOIN Categories_Description d ON c.categories_id = d.categories_id GROUP BY p.products_navn ORDER BY d.category_name, m.manufacturers_name

du vil se at jeg har givet tabellerne 'aliases' saasom jeg kalder Orders_Product for o, for ikke at vaere noedt til at gentage de lange tabel navne hele tiden.

og php koden kunne blive noget i denne retning:

$varelinier = mysql_query([ovenstaaende query]);
while($varelinie = mysql_fetch_array($varelinier))
{
  echo "<tr>";
  echo "<td>" . $varelinie['orders_id'] . "</td>";
  echo "<td>" . $varelinie['product_name'] . "</td>";
  echo "<td>" . $varelinie['total_quantity'] . "</td>";
  echo "<td>" . $varelinie['categories_name'] . "</td>";
  echo "<td>" . $varelinie['manufacturers_name'] . "</td>";
  echo "</tr>";
}

Men - din tabelstruktur er bestemt ikke optimal.  Hvis du er interesseret skal jeg foreslaa en tabelstruktur der goer jobbet et stykke lettere.
Avatar billede neo-fisk Nybegynder
13. marts 2011 - 15:35 #2
du har ganske ret, $order_supplier skal faktisk bare væk det havde jeg ikke lige fået fjernet, dog skal resten af linien bruges da den henter antalet af vare..

efter lidt tilretning af din query så den ser således ud:

$varelinier = mysql_query (" SELECT o.orders_id, o.product_name, SUM(o.product_quantity) AS total_quantity, d.categories_name, m.manufacturers_name FROM zen_orders_products o JOIN zen_products p ON o.products_id = p.products_id JOIN zen_manufacturers m ON p.manufacturers_id = m.manufacturers_id JOIN zen_categories c ON p.master_categories_id = c.parent_id JOIN zen_categories_description d ON c.categories_id = d.categories_id GROUP BY p.products_navn ORDER BY d.category_name, m.manufacturers_name")or die(mysql_error());



while($varelinie = mysql_fetch_array($varelinier))
{
  echo "<tr>";
  echo "<td>" . $varelinie['orders_id'] . "</td>";
  echo "<td>" . $varelinie['product_name'] . "</td>";
  echo "<td>" . $varelinie['total_quantity'] . "</td>";
  echo "<td>" . $varelinie['categories_name'] . "</td>";
  echo "<td>" . $varelinie['manufacturers_name'] . "</td>";
  echo "</tr>";
}


får jeg: Unknown column 'o.product_name' in 'field list'
som fejl har det evt. noget at gøre med at jeg har prefix på (zen_)?
13. marts 2011 - 16:04 #3
Det vil sige at din mysql ikke i tabellen zen_order_products kan vinde en kolonne med navn product_name.  Er der rent faktisk saadan en kolonne i tabellen?  Jeg maatte gaette paa, ud fra dit spoergsmaal, hvilke tabeller der var med hvilke kolonner og hvordan de hang sammen.
Avatar billede neo-fisk Nybegynder
13. marts 2011 - 16:50 #4
ahh okay, har lige kigget lidt videre på query'en og er kommet frem til dette:

$varelinier = mysql_query (" SELECT o.orders_id, o.products_name, SUM(o.products_quantity) AS total_quantity, d.categories_name, m.manufacturers_name FROM zen_orders_products o JOIN zen_products p ON o.products_id = p.products_id JOIN zen_manufacturers m ON p.manufacturers_id = m.manufacturers_id JOIN zen_categories c ON p.master_categories_id = c.parent_id JOIN zen_categories_description d ON c.categories_id = d.categories_id GROUP BY o.products_name ORDER BY d.categories_name, m.manufacturers_name")or die(mysql_error());

while($varelinie = mysql_fetch_array($varelinier))
{
  echo "<tr>";
  echo "<td>" . $varelinie['orders_id'] . "</td>";
  echo "<td>" . $varelinie['product_name'] . "</td>";
  echo "<td>" . $varelinie['total_quantity'] . "</td>";
  echo "<td>" . $varelinie['categories_name'] . "</td>";
  echo "<td>" . $varelinie['manufacturers_name'] . "</td>";
  echo "</tr>";
}

den kommer ikke læmgere med nogen fejl, men udskriver heller ikke noget til siden, hvis jeg laver en "echo $varelinier;" udskriver den "Resource id #143" - det kan godt være jeg lige skal lave et dump af opbygning på de tabeller der, hvis det vil være til nogen hjælp ?
13. marts 2011 - 17:15 #5
Vi er begge to galt paa den.  Jeg fik ikke WHERE klausulen med, og du oversaa det ogsaa.  Altsaa:  SELECT ...... FROM ....... WHERE o.orders_id IN ($final_ids) GROUP BY .... ORDER BY ....

Du faar ikke noget skrevet ud.  Det skyldes sandsynligvis at den ikke finder noget i tabellerne der svarer til din query.  Proev at genindsaette  ...or die(mysql_error()).  Saa faar du det at vide hvis grunden til at du ikke faar noget skrevet ud er syntaks fejl i spoergsmaalet.

Og saa, i stedet for at echoe $varelinier, saa tael hvor mange varelinier du faar ud af queryen.  Indsaet dette:

$varelinier = mysql_query(...);
$number = mysql_num_rows($varelinier);
echo "ANTAL RESULTATER: $number";

Hvis enten du faar syntaks fejl eller antallet af resultater er nul, saa har jeg nok gaettet forkert med hensyn til hvordan dine tabeller passer sammen.  Fik du kikket paa mit link hvor jeg viser hvilke tabeller med hvilke felter jeg fandt og hvilke felter i hvilke tabeller der svarer til hvilke felter i de andre tabeller.  Stemmer det?
Avatar billede neo-fisk Nybegynder
14. marts 2011 - 17:50 #6
dit billede med opbygningen af tabellerne passer 100% :)

Jeg har nu følgende:

$varelinier = mysql_query (" SELECT o.orders_id, o.products_name, SUM(o.products_quantity) AS total_quantity, d.categories_name, m.manufacturers_name FROM zen_orders_products o JOIN zen_products p ON o.products_id = p.products_id JOIN zen_manufacturers m ON p.manufacturers_id = m.manufacturers_id JOIN zen_categories c ON p.master_categories_id = c.parent_id JOIN zen_categories_description d ON c.categories_id = d.categories_id WHERE o.orders_id IN ($final_ids) GROUP BY o.products_name ORDER BY d.categories_name, m.manufacturers_name")or die(mysql_error());

$number = mysql_num_rows($varelinier);
echo "ANTAL RESULTATER: $number";

while($varelinie = mysql_fetch_array($varelinier))
{
  echo "<tr>";
  echo "<td>" . $varelinie['orders_id'] . "</td>";
  echo "<td>" . $varelinie['product_name'] . "</td>";
  echo "<td>" . $varelinie['total_quantity'] . "</td>";
  echo "<td>" . $varelinie['categories_name'] . "</td>";
  echo "<td>" . $varelinie['manufacturers_name'] . "</td>";
  echo "</tr>";
}

hvilket bare resultere i "ANTAL RESULTATER: 0" hmm, kan desværre ikke komme med de storer indputs til løsningen da jeg aldrig har arbejdet med JOINs før.. du må sige til hvis du skal bruge noget mere info :)
14. marts 2011 - 20:02 #7
Jamen hvis du faar "ANTAL RESULTATER: 0" saa hurra!  Saa er vi paa sporet:  Din mysql forespoergslen finder ikke i dine tabeller noget resultat, og det skyldes ikke syntaks fejl, for saa havde du faaet en mysql_error besked.  Altsaa maa vi naermere undersoege spoergsmaalet og tabellerne. 

Min teori er at nogle af de vaerdier der skal passe sammen ikke passer sammen. Der er fire joins i queryen.  Den foerste JOIN forventer at der i products_id i zen_orders_products kun findes vaerdier der ogsaa findes i products_id i zen_products.  Den anden JOIN forventer at der i manufacturers_id i zen_products kun findes vaerdier der ogsaa findes i manufacurers_id i zen_manufacturers, o.s.v.  Proev for hver af de fire joins at kikke paa de vaerdier du har i tabellerne for at se om det passer. 

Hvis du ikke ved manuel inspektion finder et problem, saa maa det blive en trin-for-trin procedure.

(1) Proev foerst:

$varelinier = mysql_query("SELECT * FROM zen_orders_products);
$number = mysql_num_rows($varelinier);
echo "ANTAL RESULTATER: $number";

Der SKAL du faa et resultat der er stoerre end 0.  Ellers er det forhekset.

(2)  Saa udvid til:

$varelinier = mysql_query("SELECT * FROM zen_orders_products o JOIN zen_products p ON o.products_id = p.products_id");
$number = mysql_num_rows($varelinier);
echo "ANTAL RESULTATER: $number";

Hvis du nu faar 0, saa er der ikke nogen af vaerdierne i zen_orders_products.products_id der svarer til vaerdierne i zen_orders.products_id.

(3)  Hvis du derimod faar et tal stoerre end 0, saa udvider du med endnu en join:

$varelinier = mysql_query("SELECT * FROM zen_orders_products o JOIN zen_products p ON o.products_id = p.products_id JOIN zen_manufacturers m ON p.manufacturers_id = m.manufacturers_id ");
$number = mysql_num_rows($varelinier);
echo "ANTAL RESULTATER: $number";

(4) Igen, hvis du faar 0, saa er der ingen af vaerdierne i zen_products.manufacturers_id der svarer til vaerdierne i zen_manufacturers.manufacturers_id.  Hvis du faar stoerre end 0, saa udvider du og tager det naeste join med, og hvis du der ogsaa faar stoerre end 0 udvider du med det sidste join.

Kik paa det og fortael hvilke resultater du faar.
Avatar billede neo-fisk Nybegynder
14. marts 2011 - 20:42 #8
1)
$varelinier = mysql_query("SELECT * FROM zen_orders_products");
$number = mysql_num_rows($varelinier);
echo "ANTAL RESULTATER: $number";

ANTAL RESULTATER: 60

2)
$varelinier = mysql_query("SELECT * FROM zen_orders_products o JOIN zen_products p ON o.products_id = p.products_id");
$number = mysql_num_rows($varelinier);
echo "ANTAL RESULTATER: $number";

ANTAL RESULTATER: 60

3)
$varelinier = mysql_query("SELECT * FROM zen_orders_products o JOIN zen_products p ON o.products_id = p.products_id JOIN zen_manufacturers m ON p.manufacturers_id = m.manufacturers_id ");
$number = mysql_num_rows($varelinier);
echo "ANTAL RESULTATER: $number";

ANTAL RESULTATER: 35

4)
$varelinier = mysql_query("SELECT * FROM zen_orders_products o JOIN zen_products p ON o.products_id = p.products_id JOIN zen_manufacturers m ON p.manufacturers_id = m.manufacturers_id JOIN zen_categories c ON p.master_categories_id = c.parent_id");
$number = mysql_num_rows($varelinier);
echo "ANTAL RESULTATER: $number";

ANTAL RESULTATER: 0


så det må værer noget i "JOIN zen_categories c ON p.master_categories_id = c.parent_id" den er galt
14. marts 2011 - 21:07 #9
Saa er det aabenbart ikke korrekt at vaerdierne i master_categories_id i zen_products indeholder de samme vaerdier som parent_id i zen_categories.  Kik engang paa de vaerdier du har puttet i zen_products og se hvor de gaar igen i zen_categories.  Er det i virkeligheden zen_categories.categories_id der svarer til zen_products.master_categories_id?
Avatar billede neo-fisk Nybegynder
14. marts 2011 - 21:29 #10
ahh ja det er da rigtig, efter at have ændret den til:

$varelinier = mysql_query("SELECT * FROM zen_orders_products o JOIN zen_products p ON o.products_id = p.products_id JOIN zen_manufacturers m ON p.manufacturers_id = m.manufacturers_id JOIN zen_categories c ON p.master_categories_id = c.categories_id JOIN zen_categories_description d ON c.categories_id = d.categories_id WHERE o.orders_id IN ($final_ids) GROUP BY o.products_name ORDER BY d.categories_name, m.manufacturers_name")or die(mysql_error());

$number = mysql_num_rows($varelinier);
echo "ANTAL RESULTATER: $number";

får jeg 6 linier ud, og hvis jeg laver:

while($varelinie = mysql_fetch_array($varelinier))
{
  echo "<tr>";
  echo "<td>" . $varelinie['orders_id'] . "</td>";
  echo "<td>" . $varelinie['product_name'] . "</td>";
  echo "<td>" . $varelinie['total_quantity'] . "</td>";
  echo "<td>" . $varelinie['categories_name'] . "</td>";
  echo "<td>" . $varelinie['manufacturers_name'] . "</td>";
  echo "</tr>";
}

så skriver den noget i nogen af felterne, men den mangler lige at udfylde disse 2:

echo "<td>" . $varelinie['product_name'] . "</td>";
echo "<td>" . $varelinie['total_quantity'] . "</td>";

men tror helt sikkert jeg skal have leget lidt mere med JOINs for det ser da lidt tricky ud, men man lærer jo hele tiden :)
Avatar billede neo-fisk Nybegynder
14. marts 2011 - 21:44 #11
fik lige noget i  echo "<td>" . $varelinie['total_quantity'] . "</td>";

havde glemt at vi havde fjerne den under test, så du ser min query sådan her ud:

$varelinier = mysql_query("SELECT o.orders_id, o.products_name, SUM(o.products_quantity) AS total_quantity, d.categories_name, m.manufacturers_name FROM zen_orders_products o JOIN zen_products p ON o.products_id = p.products_id JOIN zen_manufacturers m ON p.manufacturers_id = m.manufacturers_id JOIN zen_categories c ON p.master_categories_id = c.categories_id JOIN zen_categories_description d ON c.categories_id = d.categories_id WHERE o.orders_id IN ($final_ids) GROUP BY o.products_name ORDER BY d.categories_name, m.manufacturers_name")or die(mysql_error());
Avatar billede neo-fisk Nybegynder
14. marts 2011 - 21:52 #12
fandt den selv :p

der manglede lige et "s":  echo "<td>" . $varelinie['products_name'] . "</td>";

Du skal have rigtig mange tak for hjælpen :)
14. marts 2011 - 22:01 #13
Er konklusionen at du fik problemet loest?  I saa fald til lykke.  (Og er tiden saa inde til at lukke spoergsmaalet ved at acceptere mit svar #1?)  Hvis ikke, hvilke problemer er der saa tilbage?

Jeg vil stoette dit fortsaet om at laere om JOIN.  For det foerste er det slet ikke til at komme uden om i sql, for det andet er det ren logik naar man foerst faar fat paa det.

Jeg vil yderligere foreslaa at du kikker paa database normalisering.  Din tabel struktur er ikke optimal - med en bedre tabelstruktur og en enkelere navngivning kunne du have lettet det for dig selv.
Avatar billede neo-fisk Nybegynder
14. marts 2011 - 22:08 #14
Yep problemet er løst og jeg har allerede accepteret dit svar i #1 :)

Jeg kan desværre ikke ændre på strukturen da det er et eksisterende system, men jeg vil lige have det i tankerne at kigge op på det også, kunne jo værer man også kunne lære noget der..
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester