MySQL tietokannassa on kaksi taulua
- TUOTTEET, jossa on sarakkeet Tuotenimitys, Hinta ja Saldo
- TILAUKSET, jossa on Tilaajatunnus, Tuotenimitys ja Kpl.
Näytölle tulostetaan taulukko, jossa on sarakkeina Tuotenimitys ja riveinä Tilaajatunnus sekä soluissa arvona Kpl. Osa soluista jää tyhjäksi.
Nyt on ratkaistu niin, että jokaisen solun kohdalla tehdään kaksi tietokantakyselyä; $query1 = "SELECT * FROM TUOTTEET... ja $query2 = "SELECT * FROM TILAUKSET... jne. Tähän täytyy olla joku kätevämpi tapa? Tuli vastaan, kun ratkaisua hieman päivitetään muuten.
mercier kirjoitti:
Tähän täytyy olla joku kätevämpi tapa?
Juu, sitä kutsutaan JOINiksi.
https://dev.mysql.com/doc/refman/8.0/en/join.
Kyselyyn voi yksinkertaisesti laittaa monta taulua. Jos ensimmäisessä taulussa on rivit 1, 2 ja 3 ja toisessa taulussa rivit A, B ja C, tuloksiin tulevat kaikki näiden yhdistelmät eli rivit 1A, 1B, 1C, 2A, 2B, 2C, 3A, 3B ja 3C. Tuloksia voi sitten rajata normaalisti ehdoilla kyselyn WHERE-kohdassa. Tässä tapauksessa rajaukseen kuuluu, että sarake Tuotenimetys olisi molemmissa tauluissa sama.
Kahdesta taulusta tietoja hakeva kysely voisi näyttää tältä:
SELECT * FROM TUOTTEET tu, TILAUKSET ti WHERE tu.Tuotenimetys = ti.Tuotenimetys
Toisaalta tarkemmin katsoen huomataan, että tässä ei edes käytetä TUOTTEET-taulun tietoja mihinkään eli riittäisi hakea kaikki tiedot pelkästään TILAUKSET-taulusta.
SELECT * FROM TILAUKSET
Jos kuitenkin halutaan mukaan myös ne tuotteet, joille ei ole yhtään tilausta, täytyisi käyttää LEFT JOIN -rakennetta. Tällöin valitaan kaikki rivit ensimmäisestä taulusta ja kaikki yhdistelmät toiseen tauluun, mutta jos jollekin riville ei löydy yhtään ehdon täyttävää yhdistelmää, palautetaan kuitenkin ensimmäisen taulun rivi ja toisen taulun sarakkeissa vain NULL-arvot.
SELECT * FROM TILAUKSET ti LEFT JOIN TUOTTEET tu ON tu.Tuotenimetys = ti.Tuotenimetys
Tietoja voisi käsitellä näin:
// Haetaan kaikki data valmiiksi em. kyselyllä. $data0 = aja_yllä_oleva_kysely(); // Järjestetään data käytännölliseen muotoon. $data = []; foreach ($data0 as $d) { $data[$d["Tuotenimetys"]][$d["Tilaajatunnus"]] = $d["Kpl"]; } // Taulukon solun ei tarvita enää tietokantahakua: $tuotenimetys = "Petteri"; $tilaajatunnus = "Keijo"; $kpl = $data[$tuotenimetys][$tilaajatunnus] ?? null;
Metabolix kirjoitti:
...
Jos kuitenkin halutaan mukaan myös ne tuotteet, joille ei ole yhtään tilausta, täytyisi käyttää LEFT JOIN -rakennetta. ...
Tässä se ongelma juuri tuli, kun olin tarjoamassa supistettua taulukkoa.
Taulukossa tarvitaan kaikki tuotteet ja kaikki tilaukset.
Itse asiassa tarkentui, että tarvitaan myös ne TILAAJATUNNUKSET, joissa ei ole yhtään tilausta ja TUOTTEET, joista ei ole yhtään tilausta.
TILAUKSET taulussa on tältä osin siis myös tyhjiä rivejä ja TILAUKSET taulukon parempi nimi olisi TILAAJAT.
Paljonkohan tämä vaikuttaakaan tapaukseen, saa nähdä.
Kiitokset molemmille. Nyt siis JOINaamaan.
Ehkä selvin ratkaisu on hakea ei-tyhjät rivit ja käsitellä ne edellä antamani koodin tyylisesti ja sitten hakea erikseen silmukoita varten listat tilaajista ja tuotteista (kuten sinulla varmaan jo on).
Kuulostaa kyllä todella oudolta, että nuo kaksi täysin eri asiaa pitäisi saada ängettyä samaan kyselyyn. Kaikkea ei pidä yrittää pupeltaa yhteen sql-kyselyyn, koska se ei usein ole edes suorituskykyisin vaihtoehto.
Aihe on jo aika vanha, joten et voi enää vastata siihen.