pitäisi joukkueen pistepörssihaku saada tehtyä.
on kaksi taulua (esim. p ja m)
p (kentät id, etunimi, sukunimi):
id|etunimi|sukunimi |
---------------------
1|erkki |esimerkki|
2|pekka |pelimies |
m (kentät aika, tekijä, syöttäjä)
aika|tekijä|syöttäjä|
---------------------
1.00| 1| 2|
2.23| 2| 1|
5.32| 1| 3|
pitäsi saada aikaiseksi haku, jossa on kentät
id|etunimi|sukunimi-|maalit|syötöt|
-----------------------------------
1| erkki|esimerkki| 2| 1|
2| pekka|pelimies | 1| 1|
Tällaisella haulla saan tehtyä hakutuloksen, jossa on muut yllä mainituista paitsi syötöt-sarake:
"SELECT p.id AS id, p.etunimi AS etunimi, p.sukunimi AS sukunimi, COUNT(*) AS maalit FROM p, m WHERE m.tekijä = p.id GROUP BY p.id"
mutta miten samaan hakuun saisi lisättyä muitakin sarakkeita countia käyttäen, esim. tässä tapauksessa tuon syötöt. Miten siis toisen sarakkeen voisi yhdistää tuohon siten, että count-funktion käytössä uudelleen rajaus olisikin "WHERE m.syöttäjä = p.id"
Ja nyt siis nimenomaan tarkoitus olisi saada tehtyä tuo yhdellä haulla enkä halua yhdistellä tietoja jälkeenpäin
Kenttien lisääminen samaan hakuun MySQL:ssä
14
1450
Vastaukset
- taulunimi
en ole mysql:llä tehnyt paljon mitään.
Mutta jotenkin tällä tapaa...
select p.id, p.etunimi,p.sukunimi,
count(em.*) as maalit, count (er.*) as syötöt
from p, m as em, m as er
where
p.id = em.tekija
and
p.id = er.syottaja
group by p.id;
Huom! en tiedä toimiiko mutta aika lähellä kumminkin. Tarkista tulos jos syöttäjä tiedot puuttuvat, jos ei ole pakollinen tieto. left outer join ehkä mukaan tms.
Jos et saa tehtyä nii tee näkymät joita vertailet keskenään.- Female
Mikset mene rakennenäkymään, hae näitä kahta taulua sinne ja kaksoiklikkaa niitä tetueita sinne jotka haluat taulukkonäkymään?
- I.Proqatlis
Ei tässä tarvita group by –rakennetta ollenkaan.
Pitää vain tietää, että selectissä voidaan käyttää alikyselyä tähän tapaan:
select
p.id,
p.etunimi,
p.sukunimi,
(select count(*) from maalit m where p.id = m.tekija) as tehdyt,
(select count(*) from maalit m where p.id = m.syottaja) as syötetyt
from
pelaajat p;
Tämä antaa sinulle vastauksen kysymykseesi ! Yksinkertaista :-)- SQL
Tuohan kuulostaa jo todella helpolta.
Ei ainakaan suoraan näin toiminut, eikä myöskään näin (lisätty AS -sanat):
select
p.id,
p.etunimi,
p.sukunimi,
(select count(*) from maalit AS m where p.id = m.tekija) as tehdyt,
(select count(*) from maalit AS m where p.id = m.syottaja) as syötetyt
from
pelaajat AS p
Virheeksi tulee molemmilla seuraava:
#1064 - You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'select count(*) from maalit m where p.id = m.tekija) as tehdy - I.Proqatlis
SQL kirjoitti:
Tuohan kuulostaa jo todella helpolta.
Ei ainakaan suoraan näin toiminut, eikä myöskään näin (lisätty AS -sanat):
select
p.id,
p.etunimi,
p.sukunimi,
(select count(*) from maalit AS m where p.id = m.tekija) as tehdyt,
(select count(*) from maalit AS m where p.id = m.syottaja) as syötetyt
from
pelaajat AS p
Virheeksi tulee molemmilla seuraava:
#1064 - You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'select count(*) from maalit m where p.id = m.tekija) as tehdyHmm. Olen kyllä aivan varma, että tuo kysely toimii MySQL 5.0-versiossa. Minä nimittäin loin kuvaamasi taulut tietokantaan sekä hieman testiaineistoa, ja tulos oli erinomainen.
Nytkin jos copypastean viestistäni tuon SQL-operaation MySQL Query Browserin kyselyikkunaan, niin se toimii edelleenkin.
Minulla on myös Aqua Data Studio -käyttöliittymä, ja tätäkin kautta annettuna kysely toimii.
Saamasi virheilmoitus viittaa siihen, että sinulla käytössä oleva MySQL-versio ei tajua tällaisia alikyselyitä. Itselläni ei ole vanhempia versioita, mutta olen lukenut, että niistä puuttuu koko joukko ominaisuuksia, jotka ovat uusimmassa.
Tarkista, mikä MySQL-versio sinulla on käytössä ja jos mahdollista, niin päivitä uudempaan. - ------
SQL kirjoitti:
Tuohan kuulostaa jo todella helpolta.
Ei ainakaan suoraan näin toiminut, eikä myöskään näin (lisätty AS -sanat):
select
p.id,
p.etunimi,
p.sukunimi,
(select count(*) from maalit AS m where p.id = m.tekija) as tehdyt,
(select count(*) from maalit AS m where p.id = m.syottaja) as syötetyt
from
pelaajat AS p
Virheeksi tulee molemmilla seuraava:
#1064 - You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'select count(*) from maalit m where p.id = m.tekija) as tehdyMikäs MySQL?
MySQL 5 tukee vasta alikyselyitä, joten MySQL 4.x tuo ei toimine ja taitaa ilmaista asian juuri tuommosella virheilmoituksella. Toki tuon saa toimimaan myös MySQL 4 kunhan vain hajottaa alikyselyt, mut silloin joudut tekemään muutaman kyselyn ja yhdistää tiedot.
AS ei ole pakollinen joskin sitä kannattaa käyttää selkeyttää, ja yleensä kaik tietokanta käskyt kirjoitetaan isolla näin ne erottaa helpost muista.
Vaik tuo kysely kuulostaakin helpolta niin SELECT lauseessa olevat alikyselyt ovat aina raskaita ja niitä kannattaa välttää mahdollisuuksien mukaan. - ------
I.Proqatlis kirjoitti:
Hmm. Olen kyllä aivan varma, että tuo kysely toimii MySQL 5.0-versiossa. Minä nimittäin loin kuvaamasi taulut tietokantaan sekä hieman testiaineistoa, ja tulos oli erinomainen.
Nytkin jos copypastean viestistäni tuon SQL-operaation MySQL Query Browserin kyselyikkunaan, niin se toimii edelleenkin.
Minulla on myös Aqua Data Studio -käyttöliittymä, ja tätäkin kautta annettuna kysely toimii.
Saamasi virheilmoitus viittaa siihen, että sinulla käytössä oleva MySQL-versio ei tajua tällaisia alikyselyitä. Itselläni ei ole vanhempia versioita, mutta olen lukenut, että niistä puuttuu koko joukko ominaisuuksia, jotka ovat uusimmassa.
Tarkista, mikä MySQL-versio sinulla on käytössä ja jos mahdollista, niin päivitä uudempaan.Pyh olit nopeempa :(
Juu MySQL 4.x puuttu vaik mitä ominaisuuksia kuten alikyselyt, triggerit jne... joiden puuttumisen takia joutu kikkailee vaik miten.
Version saa selville SELECT VERSION(); kyselyllä. - SQL
------ kirjoitti:
Pyh olit nopeempa :(
Juu MySQL 4.x puuttu vaik mitä ominaisuuksia kuten alikyselyt, triggerit jne... joiden puuttumisen takia joutu kikkailee vaik miten.
Version saa selville SELECT VERSION(); kyselyllä.Jeps. Kiitos kaikille avusta, versio on tosiaankin vain nelonen:
4.0.27-standard-log
Täytyypä alkaa pommittaa palveluntarjoajaa, jotta päivittäisi uudempaan...
Ei kikkailu niin kiinnosta. - ------
SQL kirjoitti:
Jeps. Kiitos kaikille avusta, versio on tosiaankin vain nelonen:
4.0.27-standard-log
Täytyypä alkaa pommittaa palveluntarjoajaa, jotta päivittäisi uudempaan...
Ei kikkailu niin kiinnosta.Leikitkös PHP5:den kanssa?
Jos niin tällöin on mahollista käyttää SQLiteä, joka taitaa nuo alikyselytkin jne...
Katsos http://fi.php.net/manual/en/ref.pdo.php ja http://fi.php.net/manual/en/ref.sqlite.php jos mahollista niin PDO kannattaa käyttää tällöin SQLite3 muutoin SQLite 2.84 muistaakseni. Mut molemmat taitaa nuo alikyselyt.
Vilkaiseppas http://www.personal.fi/ jos ilmainen palveluntarjoaja kiinostaa, siel MySQL5 käytös.
- I.Proqatlis
... systeemin arkkitehtuurista.
Jos minulla olisi vapaat kädet rakentaa tämä systeemi, niin tekisin näin.
Lisään pelaajatauluun kentät tehdyt_maalit ja syotetyt_maalit. Nämähän ovat pelaajaan hyvin läheisesti liittyviä tietoja. Aiemmassa versiossa nämä tiedot piti alikyselyillä hakea maalit-taulusta. Jokaisen pelaajan kohdalla kahlattiin maalit-taulu kahdesti läpi etsittäessä tehtyjä ja syötettyjä maaleja. Tässä esittämässäni ratkaisussa nämä tiedot voidaan lukea suoraan pelaajan tiedoista yksinkertaisella selectillä.
Kuinka saadaan tiedot pelaajataulussa pysymään ajan tasalla? Luon triggerin, joka reagoi uuden rivin lisäämiseen maalit-tauluun. Triggeri päivittää maalin tehneen ja syöttäneen (jos syöttäjä on olemassa) pelaajan tiedot.
Meillä on siis seuraavat taulut:
Pelaajat
---------
id
etunimi
sukunimi
tehdyt_maalit
syotetyt_maalit
Maalit
--------
aika
tekija
syottaja
Triggerin sisältö on tällainen:
CREATE TRIGGER jengi_teki_maalin AFTER INSERT ON maalit
FOR EACH ROW
BEGIN
UPDATE pelaajat
SET tehdyt_maalit = tehdyt_maalit 1
WHERE
id = NEW.tekija;
if NEW.syottaja is not null then
UPDATE pelaajat
SET syotetyt_maalit = syotetyt_maalit 1
WHERE
id = NEW.syottaja;
end if;
END
Mutta kuten aiemmassa viestissä on sanottu, triggerien käyttö vaatii, että MySQL-tietokanta on tasoa 5.
Pointtini siis on, että arkkitehtuurin suunnittelulla voidaan vaikuttaa paljon siihen, kuinka monimutkaisia ja raskaita SQL-operaatioita systeemissä tarvitaan!- tohlo
> CREATE TRIGGER jengi_teki_maalin
> AFTER INSERT ON maalit
> FOR EACH ROW
> BEGIN
> UPDATE pelaajat
> SET tehdyt_maalit = tehdyt_maalit 1
> ...
Entä jos maalit-tauluun lisättiin virheellinen rivi, esim. pelaajan id oli virheellinen tai maalia ei hyväksyttykään, vaikka se jo tauluun lisättiin? Laskurisi ei olekaan tällaisten jälkeen enää synkronissa oikean tilanteen kanssa. :)
Idea kuitenkin sinulla oli se, että tallennetaan koostefunktion (count) tulos tauluunlisäysten yhteydessä, jotta lukumäärää ei aina tarvitse laskea perustietojen avulla uudelleen. Periaatteessa ok idea, mutta tässä täytyy ottaa huomioon kaikki sivuvaikutukset.
Minä en kovin pienellä datamäärällä lähtisi käyttämään tällaista tallennustapaa. Vasta jos maaleja on tallessa (satoja) miljoonia ja datan määrä oikeasti johtaa siihen, että haut ovat optimoituinakin tehottomia (eikä sovelluskoodin muokkauksella tai taulujen indekseilläkään saada nopeutta), kannattaa alkaa tallennella välituloksia. - I.Proqatlis
tohlo kirjoitti:
> CREATE TRIGGER jengi_teki_maalin
> AFTER INSERT ON maalit
> FOR EACH ROW
> BEGIN
> UPDATE pelaajat
> SET tehdyt_maalit = tehdyt_maalit 1
> ...
Entä jos maalit-tauluun lisättiin virheellinen rivi, esim. pelaajan id oli virheellinen tai maalia ei hyväksyttykään, vaikka se jo tauluun lisättiin? Laskurisi ei olekaan tällaisten jälkeen enää synkronissa oikean tilanteen kanssa. :)
Idea kuitenkin sinulla oli se, että tallennetaan koostefunktion (count) tulos tauluunlisäysten yhteydessä, jotta lukumäärää ei aina tarvitse laskea perustietojen avulla uudelleen. Periaatteessa ok idea, mutta tässä täytyy ottaa huomioon kaikki sivuvaikutukset.
Minä en kovin pienellä datamäärällä lähtisi käyttämään tällaista tallennustapaa. Vasta jos maaleja on tallessa (satoja) miljoonia ja datan määrä oikeasti johtaa siihen, että haut ovat optimoituinakin tehottomia (eikä sovelluskoodin muokkauksella tai taulujen indekseilläkään saada nopeutta), kannattaa alkaa tallennella välituloksia.Kyllä minä olen ottanut huomioon kaikki sivuvaikutukset. Satutko tietämään, että on mahdollista luoda myös sellaisia triggereitä, jotka reagoivat rivillä olevien tietojen päivittämiseen tai koko rivin poistamiseen.
Jos siis maalin tehnyttä pelaajaa korjataan, niin update-triggeri nuuskii rivillä olleen vanhan ja uuden pelaajan ja suorittaa pelaajatiedoissa olevien laskurien päivitykset.
Jos koko rivi poistetaan, niin triggeri käy vähentämässä yhden maalin tekijältä ja yhden syöttäjältä (jos sellainen oli).
Siis triggeritoiminta pitää koko ajan yllä oikeita arvoja pelaajatiedoissa olevissa laskureissa. - I.Proqatlis
tohlo kirjoitti:
> CREATE TRIGGER jengi_teki_maalin
> AFTER INSERT ON maalit
> FOR EACH ROW
> BEGIN
> UPDATE pelaajat
> SET tehdyt_maalit = tehdyt_maalit 1
> ...
Entä jos maalit-tauluun lisättiin virheellinen rivi, esim. pelaajan id oli virheellinen tai maalia ei hyväksyttykään, vaikka se jo tauluun lisättiin? Laskurisi ei olekaan tällaisten jälkeen enää synkronissa oikean tilanteen kanssa. :)
Idea kuitenkin sinulla oli se, että tallennetaan koostefunktion (count) tulos tauluunlisäysten yhteydessä, jotta lukumäärää ei aina tarvitse laskea perustietojen avulla uudelleen. Periaatteessa ok idea, mutta tässä täytyy ottaa huomioon kaikki sivuvaikutukset.
Minä en kovin pienellä datamäärällä lähtisi käyttämään tällaista tallennustapaa. Vasta jos maaleja on tallessa (satoja) miljoonia ja datan määrä oikeasti johtaa siihen, että haut ovat optimoituinakin tehottomia (eikä sovelluskoodin muokkauksella tai taulujen indekseilläkään saada nopeutta), kannattaa alkaa tallennella välituloksia.Sinä epäilit, etten ollut ottanut huomioon kaikkia sivuvaikutuksia. Niinpä esitän kaikki triggerit aivan konkreettisesti MySQL-koodin tasolla. Näet, kuinka triggerit reagoivat kaikkiin muutoksiin.
Palstan muut lukijat voivat tästä saada ideoita triggerien käyttöön :-)
1. Se, joka reagoi uuden rivin lisäykseen, on aiemmassa viestissäni.
2. Triggeri nimeltä hylatty_maali hoitaa päivitykset, jos kirjattu rivi poistetaan.
3. Triggeri, jonka nimi on tekija_korjaus, käsittelee tapaukset, joissa maalin tekijää tai syöttäjää muutetaan.
CREATE TRIGGER hylatty_maali AFTER DELETE ON maalit
FOR EACH ROW
BEGIN
UPDATE pelaajat
SET tehdyt_maalit = tehdyt_maalit - 1
WHERE id = OLD.tekija;
if OLD.syottaja is not null then
UPDATE pelaajat
SET syotetyt_maalit = syotetyt_maalit - 1
WHERE id = OLD.syottaja;
end if;
END
* * * * * * * * * * * * * *
CREATE TRIGGER tekija_korjaus after UPDATE ON maalit
FOR EACH ROW
BEGIN
if NEW.tekija OLD.tekija then
UPDATE pelaajat
SET tehdyt_maalit = tehdyt_maalit - 1
WHERE id = OLD.tekija;
UPDATE pelaajat
SET tehdyt_maalit = tehdyt_maalit 1
WHERE id = NEW.tekija;
end if;
if ifnull(NEW.syottaja, 0) ifnull(OLD.syottaja, 0) then
if OLD.syottaja is not null then
UPDATE pelaajat
SET syotetyt_maalit = syotetyt_maalit - 1
WHERE id = OLD.syottaja;
end if;
if NEW.syottaja is not null then
UPDATE pelaajat
SET syotetyt_maalit = syotetyt_maalit 1
WHERE id = NEW.syottaja;
end if;
end if;
END
- SQL
Entäs tällainen tilanne:
kaksi taulua (p ja m)
p(kentät id, nimi)
id|nimi |
-------------
1|erkki |
2|pekka |
m(kentät id, a1, a2)
id|a1|a2|
---------
1| 2| 2|
2| 1| 1|
3| 1| 2|
4| 2| 3|
Ja pitäisi saada haku, jossa on seuraavat tiedot:
id|nimi |a|
-----------
1|erkki|2|
2|pekka|1|
, jossa siis a sarake on numero 1:sten määrä taulukossa m (erkillä sarakkeessa a1 ja pekalla a2). Kun siis sarakkeessa m.a1 on 2 kappaletta numero 1:stä, niin erkin sarakkeeseen hakutuloksessa tulee 2. Ja pekalla vastaavasti 1.
Seuraavalla haulla molempien rivien arvoksi tulee 3, joka on siis molemmissa sarakkeissa yhteensä oleva ykkösten määrä. (Mikäli en aivan väärin laskenut)
SELECT
p.id AS id,
p.nimi AS nimi,
(SELECT count( * ) FROM m WHERE CONCAT('a', p.id) = 1) AS a
FROM p
Ymmärrän siis (toivottavasti), mikä tässä on väärin, mutta en osaa kirjoittaa oikeanlaista koodia...
Ideoita?
Ketjusta on poistettu 0 sääntöjenvastaista viestiä.
Luetuimmat keskustelut
Kotkalainen Demari Riku Pirinen vangittu Saksassa lapsipornosta
https://www.kymensanomat.fi/paikalliset/8081054 Kotkalainen Demari Riku Pirinen vangittu Saksassa lapsipornon hallussapi862331Olen tosi outo....
Päättelen palstajuttujen perusteella mitä mieltä minun kaipauksen kohde minusta on. Joskus kuvittelen tänne selkeitä tap182267Vanhalle ukon rähjälle
Satutit mua niin paljon kun erottiin. Oletko todella niin itsekäs että kuvittelet että huolisin sut kaiken tapahtuneen191788- 1051477
Maisa on SALAKUVATTU huumepoliisinsa kanssa!
https://www.seiska.fi/vain-seiskassa/ensimmainen-yhteiskuva-maisa-torpan-ja-poliisikullan-lahiorakkaus-roihuaa/1525663911440Hommaatko kinkkua jouluksi?
Itse tein pakastimeen n. 3Kg:n murekkeen sienillä ja juustokuorrutuksella. Voihan se olla, että jonkun pienen, valmiin k1631248Aatteleppa ite!
Jos ei oltaisikaan nyt NATOssa, olisimme puolueettomana sivustakatsojia ja elelisimme tyytyväisenä rauhassa maassamme.2571042- 63953
- 78919
Omalääkäri hallituksen utopia?
Suurissa kaupungeissa ja etelässä moinen onnistunee. Suuressa osassa Suomea on taas paljon keikkalääkäreitä. Mitenkäs ha174903