Pieniä kysymyksiä ohjelmoinnista

Liittynyt
17.10.2016
Viestejä
5 658
Eikös tuo MULTILINE-optio ole juurikin tuo "pieni muokkaus". Silloin siis dollarimerkki matchaa sekä rivinvaihdot että stringin lopun. Eli nuo pingin ja downloadin \s-merkit voisi myös korvata $:lla, jolloin kaikki toimii riippumatta siitä missä järjestyksessä rivit on listattu.
Erinomainen huomio, pitää paikkaansa. Nopeasti nakuttelin vaan sopivat patternit ja testasin, enkä miettinyt tuota MULTILINE-flagia sen enempää. :)
 
Liittynyt
19.10.2016
Viestejä
1 690
Eikös tuo MULTILINE-optio ole juurikin tuo "pieni muokkaus". Silloin siis dollarimerkki matchaa sekä rivinvaihdot että stringin lopun. Eli nuo pingin ja downloadin \s-merkit voisi myös korvata $:lla, jolloin kaikki toimii riippumatta siitä missä järjestyksessä rivit on listattu.
Erinomainen huomio, pitää paikkaansa. Nopeasti nakuttelin vaan sopivat patternit ja testasin, enkä miettinyt tuota MULTILINE-flagia sen enempää. :)
Jees, kiitos tästä. Tällä pätkällä lähti graafia syntymään:

Koodi:
ping = re.findall('LATENCY\=(.*?)$', response, re.MULTILINE)
download = re.findall('DOWNLOAD_SPEED\=(.*?)$', response, re.MULTILINE)
upload = re.findall('UPLOAD_SPEED\=(.*?)$', response, re.MULTILINE)
jitter = re.findall('JITTER\=(.*?)$', response, re.MULTILINE)
Tiketti vetämässä yhteyden laadusta ja nopeuden vaihtelusta, saan hieman logia tällä tavalla.
 
Liittynyt
17.10.2016
Viestejä
5 331
Mulla on vähän vastaava speedtest-juttu, tosin data kiertää zabbixin kautta grafanaan koska zabbixissa mulla on vielä tiettyjä triggereitä tuon nopeustestidatan kanssa jotka lähettävät mulle telegramiin viestiä tietyissä tilanteissa. Ei ole ehkä kauneita mahdollista koodia mutta toimii itselläni. Tuota siis ajelen cronilla tietyin väliajoin ja se lähettää pingin,downloadin ja uploadin zabbixiin ja grafana taas hakee zabbixista tuon datan ja piirtää käppyrää.
Koodi:
from pyzabbix import ZabbixMetric, ZabbixSender
import speedtest

servers = [4549]    # Elisa Oyj
# If you want to test against a specific server
# servers = [1234]

s = speedtest.Speedtest()
s.get_servers(servers)
s.get_best_server()
s.download()
s.upload()
s.results.share()

results_dict = s.results.dict()
data_dl = results_dict["download"]
data_ul = results_dict["upload"]
data_pi = results_dict["ping"]

packet = [
  ZabbixMetric('internet', 'download', data_dl),
  ZabbixMetric('internet', 'upload', data_ul),
  ZabbixMetric('internet', 'ping', data_pi)
]

zbx = ZabbixSender('zabbixserver.lan')
result = zbx.send(packet)
 
Viimeksi muokattu:
Liittynyt
14.12.2016
Viestejä
1 297
Mulla on vähän vastaava speedtest-juttu, tosin data kiertää zabbixin kautta grafanaan koska zabbixissa mulla on vielä tiettyjä triggereitä tuon nopeustestidatan kanssa jotka lähettävät mulle telegramiin viestiä tietyissä tilanteissa. Ei ole ehkä kauneita mahdollista koodia mutta toimii itselläni. Tuota siis ajelen cronilla tietyin väliajoin ja se lähettää pingin,downloadin ja uploadin zabbixiin ja grafana taas hakee zabbixista tuon datan ja piirtää käppyrää.
Python:
from pyzabbix import ZabbixMetric, ZabbixSender
import speedtest

servers = [4549]    # Elisa Oyj
# If you want to test against a specific server
# servers = [1234]

s = speedtest.Speedtest()
s.get_servers(servers)
s.get_best_server()
s.download()
s.upload()
s.results.share()

results_dict = s.results.dict()
data_dl = results_dict["download"]
data_ul = results_dict["upload"]
data_pi = results_dict["ping"]

packet = [
  ZabbixMetric('internet', 'download', data_dl),
  ZabbixMetric('internet', 'upload', data_ul),
  ZabbixMetric('internet', 'ping', data_pi)
]

zbx = ZabbixSender('zabbixserver.lan')
result = zbx.send(packet)
On muuten värisokealle ihan blankoa.
 
Liittynyt
17.10.2016
Viestejä
5 331
Otin python-värikoodauksen pois, ilmeisesti nuo syntax-highlightit ei toimi kovin kivasti eri teemoilla ja varsinkaan värisokeilla.
 
Liittynyt
18.10.2016
Viestejä
473
Olen koittanut taas laoitella koodaukseen tutustumista ja hieman askarrella microPythonilla. Koitan värkkäillä venttiillien säätöä. Venttiilit saisivat parametrit sarjaliikenteellä ja stm32 hoitaa sitten ohjaukset.

Olen koittanut ensin saada koodin palasia toimimaan "yksinään" ja lopuksi sitten koitan saada ympättyä kaikki yhteen. Nyt askartelen tuota sarjaliikennettä, se "toimii", mutta en ole keksinyt miten saan yhdistettyä tavuja?
Eli luen tavut ja lykkään array:hin
Koodi:
    rData = bytearray(6)
    uart.readinto(rData)
Tuosta on/olisi tarkoitus poimia parameterit talteen, koittaa väsätä joku crc yms. noiden yksittäisten tavujen "käyttö" onnistuu, mutta niiden yhdistäminen? Eli haluasin, että osa tavuista yhdistettäisiin jotta saisin 16bit inttejä.

Eli esim nuo 6 tavua 8bit, 16bit, 16bit, 8bit. Jolloin [1:2] ja [3:4] "nivotaan yhteen".
 
Liittynyt
28.12.2016
Viestejä
1 579
Olen koittanut taas laoitella koodaukseen tutustumista ja hieman askarrella microPythonilla. Koitan värkkäillä venttiillien säätöä. Venttiilit saisivat parametrit sarjaliikenteellä ja stm32 hoitaa sitten ohjaukset.

Olen koittanut ensin saada koodin palasia toimimaan "yksinään" ja lopuksi sitten koitan saada ympättyä kaikki yhteen. Nyt askartelen tuota sarjaliikennettä, se "toimii", mutta en ole keksinyt miten saan yhdistettyä tavuja?
Eli luen tavut ja lykkään array:hin
Koodi:
    rData = bytearray(6)
    uart.readinto(rData)
Tuosta on/olisi tarkoitus poimia parameterit talteen, koittaa väsätä joku crc yms. noiden yksittäisten tavujen "käyttö" onnistuu, mutta niiden yhdistäminen? Eli haluasin, että osa tavuista yhdistettäisiin jotta saisin 16bit inttejä.

Eli esim nuo 6 tavua 8bit, 16bit, 16bit, 8bit. Jolloin [1:2] ja [3:4] "nivotaan yhteen".
Struct:lla tuo onnistuu:
struct.unpack('=bhhb',rData)

 
Liittynyt
18.10.2016
Viestejä
473
Liittynyt
28.12.2016
Viestejä
1 579
Yhtäsuuruus merkki kertoo onko data big tai little endian. Pikaisesti kun testasin mulla niin ei toiminut ilman sitä. Riippuunee python versiosta tarviiko sitä vai ei. Tuon pitäisi kuitenkin toimia kaikilla versioilla.
 
Liittynyt
17.10.2016
Viestejä
5 331
Struct:lla tuo onnistuu:
struct.unpack('=bhhb',rData)

Kiitoksia minunkin puolesta, noin kolme vuotta sitten tuli tehtyä yksi konversiosofta jossa käpisteltiin aika paljon bytearrayita ja silloin koitin jotain vastaavaa googletella mutta ei sattunut osumaan vastaan tuota. Tuli sitten vähän vastaava toiminnallisuus jälleen kerran koodattua ihan itse alusta asti ja tuo konversiosofta on ehkä juuri sen takia aikamoista spagettikoodia paikoitellen. Siinä on pari bugiakin vielä mutta jos nyt ehkä jaksaisi siivoilla koodia ja koittaa jos saisi ne pari bugiakin pois. Pikkuhiljaa alkaa kyllä tuntua että pythonista löytyy ihan mitä funktioita sun muita vaan kunhan vaan keksii ne.
 
Liittynyt
18.10.2016
Viestejä
473
Yhtäsuuruus merkki kertoo onko data big tai little endian. Pikaisesti kun testasin mulla niin ei toiminut ilman sitä. Riippuunee python versiosta tarviiko sitä vai ei. Tuon pitäisi kuitenkin toimia kaikilla versioilla.
Hmm, yhtäsuuruusmerkki heittää "Bad typecoden". Google auttaa, eli ustruct ei tue tuota, "Supported size/byte order prefixes: @, <, >, ! "

Oisko auttaa tuossa arrayn koossa? Eli miksi tuo "ei mahdu" bytearray(6) vaan vaatii 7.
struct.calcsize('BHHB') palauttaa 7.
Hieman hankaloittaa kun lähetän 6 tavua, mutta tuo array vaatii 7:
Eli lähetän:
Koodi:
01 01 01 01 01 01
Ja koodissa sitten:
Koodi:
bytearray(b'\x01\x01\x01\x01\x01\x01\x00')
(1, 257, 257, 0)
Niinkuin, näkyy niin siellä on toi "extra" x00 arrayssa...
 
Liittynyt
17.10.2016
Viestejä
1 115
Oisko auttaa tuossa arrayn koossa? Eli miksi tuo "ei mahdu" bytearray(6) vaan vaatii 7.
struct.calcsize('BHHB') palauttaa 7.
Kuten tuossa struct dokkarin alussa olevassa nootissa sanotaan, ilman tuota ensimmäistä tavukoko/järjestys/tasausmäärettä mennään oletuksena raudan C natiivilla joka ei välttämättä ole pakattua dataa: Data structure alignment - Wikipedia

TL;DR
Jos micropythonille ei kelpaa = niin joudut käyttämään <:ä tai >:ä riippuen käytetystä endiannessista tai laittamaan paddingit oikeaan paikkaan.
 
Liittynyt
18.10.2016
Viestejä
473
Kuten tuossa struct dokkarin alussa olevassa nootissa sanotaan, ilman tuota ensimmäistä tavukoko/järjestys/tasausmäärettä mennään oletuksena raudan C natiivilla joka ei välttämättä ole pakattua dataa: Data structure alignment - Wikipedia

TL;DR
Jos micropythonille ei kelpaa = niin joudut käyttämään <:ä tai >:ä riippuen käytetystä endiannessista tai laittamaan paddingit oikeaan paikkaan.
Kiitoksia, tämä olikin simpppeli ja olisi itsekkin pitänyt varmaan tuosta dokkarista tajuta, eli toimii hienosti kun lisää bytorderin jolla size on "standard".

Tuo struct siis palauttaa tuplen, ennen kuin kauheasti kikkailen lisää niin käytän extendiä muuttaakseni taas tuon tuplen:
Koodi:
    rParams = struct.unpack('<BHHB', rData)
    x = []
    x.extend(rParams)

    if x[1] == 1:
        duty = x[2]

    else:
        duty = 100
Eli onko tuo extendin käyttö ihan ok?
 
Liittynyt
17.10.2016
Viestejä
1 115
Tuo struct siis palauttaa tuplen, ennen kuin kauheasti kikkailen lisää niin käytän extendiä muuttaakseni taas tuon tuplen:
Koodi:
    rParams = struct.unpack('<BHHB', rData)
    x = []
    x.extend(rParams)

    if x[1] == 1:
        duty = x[2]

    else:
        duty = 100
Eli onko tuo extendin käyttö ihan ok?
Ei tuossa välttämättä extendiä tarvita, toimii toki mutta itse tekisin jotakin tällaista
Koodi:
  x = list(rParams)
  # Tai jos ei tuplea tarvita mihinkään niin suoraan listaksi
  rParams = list(struct.unpack('<BHHB', rData))
Tuplekin toimisi sellaisenaan tuossa lyhyessä pätkässä minkä laitoit, mutta oletan että käytät sitä muuhunkin niin paha sanoa.
 
Liittynyt
18.10.2016
Viestejä
473
Ei tuossa välttämättä extendiä tarvita, toimii toki mutta itse tekisin jotakin tällaista
Koodi:
  x = list(rParams)
  # Tai jos ei tuplea tarvita mihinkään niin suoraan listaksi
  rParams = list(struct.unpack('<BHHB', rData))
Tuplekin toimisi sellaisenaan tuossa lyhyessä pätkässä minkä laitoit, mutta oletan että käytät sitä muuhunkin niin paha sanoa.
Aa en tajununnutkaan, että ton voi heittää suoraan listaksi. Paljon kiitoksia
 
Liittynyt
23.10.2016
Viestejä
658
Käytän yhdessä projektissa ORMia (Prisma) ja projekti pitää sisällään tietokannan skeematiedoston (schema.prisma). Tarvitsisin tuota samaa skeematiedostoa sivuprojektissa.

Miten toteutan tuon tiedoston jakamisen kahden eri projektin kesken? En voi vaan kopipastettaa tuota tiedostoa, koska se voi muuttua ja muuttuukin usein devausvaiheessa.
 
Liittynyt
13.11.2016
Viestejä
1 514
Käytän yhdessä projektissa ORMia (Prisma) ja projekti pitää sisällään tietokannan skeematiedoston (schema.prisma). Tarvitsisin tuota samaa skeematiedostoa sivuprojektissa.

Miten toteutan tuon tiedoston jakamisen kahden eri projektin kesken? En voi vaan kopipastettaa tuota tiedostoa, koska se voi muuttua ja muuttuukin usein devausvaiheessa.
Teet kirjaston jota käytät dependencynä molemmissa projekteissa.
 
Liittynyt
18.10.2016
Viestejä
272
Käytän yhdessä projektissa ORMia (Prisma) ja projekti pitää sisällään tietokannan skeematiedoston (schema.prisma). Tarvitsisin tuota samaa skeematiedostoa sivuprojektissa.

Miten toteutan tuon tiedoston jakamisen kahden eri projektin kesken? En voi vaan kopipastettaa tuota tiedostoa, koska se voi muuttua ja muuttuukin usein devausvaiheessa.
Toivottavasti ymmärsin oikein, eli kyseessä NodeJS-ympäristö? Ja schema.prisma lienee module.exports kamaa?

Helpointa lienee viitata package.json:issa kyseiseen tiedostoon joko paikallisesti tai sitten git-repon kautta, tyyliin:
JavaScript:
{
    dependencies: {
        "prisma-schema-local": "file:/<path_to_file>/schema.prisma",
        "prisma-schema-git": "git:<url_to_repo/schema.prisma",
    }
}
Ja tämän jälkeen vain esimerkiksi `import PrismaSchema from 'prisma-schema-local'`
 
Liittynyt
23.10.2016
Viestejä
658
Toivottavasti ymmärsin oikein, eli kyseessä NodeJS-ympäristö? Ja schema.prisma lienee module.exports kamaa?

Helpointa lienee viitata package.json:issa kyseiseen tiedostoon joko paikallisesti tai sitten git-repon kautta, tyyliin:
JavaScript:
{
    dependencies: {
        "prisma-schema-local": "file:/<path_to_file>/schema.prisma",
        "prisma-schema-git": "git:<url_to_repo/schema.prisma",
    }
}
Ja tämän jälkeen vain esimerkiksi `import PrismaSchema from 'prisma-schema-local'`
Juu Nodesta kyse. Miten tämä käytännössä menee? Tuo prisma olettaa että projektin ./prisma kansiosta löytyy tuo prisma.schema-tiedosto.
 
Liittynyt
23.10.2016
Viestejä
658
Tuli eteen toinen kysymys.

Mikä on oikea tapa määrittää muuttuvia relaatioita SQL:ssä?

Esimerkki:

Koodi:
TauluA

id Int
name String

--------------

TauluB

id Int
name String
tauluAid
Eli mulla on kaksi taulua A ja B. Kun haen TauluB:stä jonkun rivin, niin sen pitäisi vuodesta riippuen viitata tiettyyn TauluA:n riviin. Nyt olen tehny tuon siten, että päivitän TauluB:hen aina tällä hetkellä voimassa olevan viittauksen, mutta tällä tavalla esim. kaikki viime vuoden tilastot ovat rikki, koska referenssi on vaihtunut.
 
Liittynyt
14.12.2016
Viestejä
1 297
Tuli eteen toinen kysymys.

Mikä on oikea tapa määrittää muuttuvia relaatioita SQL:ssä?

Esimerkki:

Koodi:
TauluA

id Int
name String

--------------

TauluB

id Int
name String
tauluAid
Eli mulla on kaksi taulua A ja B. Kun haen TauluB:stä jonkun rivin, niin sen pitäisi vuodesta riippuen viitata tiettyyn TauluA:n riviin. Nyt olen tehny tuon siten, että päivitän TauluB:hen aina tällä hetkellä voimassa olevan viittauksen, mutta tällä tavalla esim. kaikki viime vuoden tilastot ovat rikki, koska referenssi on vaihtunut.
En täysin ymmärrä kysymystä, mutta eikö riitä että lisäät toiseen tai tarvittaessa molempiin tauluihin kentän vuosi, jos data ei voi jostain syystä olla yhdessä taulussa, mikä olisi varmaan sen yksinkertaisin vaihtoehto.

Jos taas teet joinin taulujen välillä samalla id:llä, niin samassa taulussa voi olla sama "id" eri vuosillakin eli eri riveinä. Tosin id-kenttä ei voi olla silloin uniikki toisessa taulussa, mutta onhan tuossa jo esim. tuo "taulun id" kenttä, mitä voi käyttää joiniin. Id:t on tapana pitää uniikkeina tauluissa.
 
Viimeksi muokattu:
Liittynyt
17.01.2018
Viestejä
1 997
Tuli eteen toinen kysymys.

Mikä on oikea tapa määrittää muuttuvia relaatioita SQL:ssä?

Esimerkki:

Koodi:
TauluA

id Int
name String

--------------

TauluB

id Int
name String
tauluAid
Eli mulla on kaksi taulua A ja B. Kun haen TauluB:stä jonkun rivin, niin sen pitäisi vuodesta riippuen viitata tiettyyn TauluA:n riviin. Nyt olen tehny tuon siten, että päivitän TauluB:hen aina tällä hetkellä voimassa olevan viittauksen, mutta tällä tavalla esim. kaikki viime vuoden tilastot ovat rikki, koska referenssi on vaihtunut.
Jos taulujen A ja B sisältö ei muuten muutu ajan mukaan (siis vuodesta/kuukaudesta/päivästä/jne riippuen) muuten kuin tuo viittaus B->A niin voit tehdä taulujen välille linkin jossa on vuosi.

Koodi:
TauluA (
id Int,
name String
)

TauluB (
id Int,
name String
)

LinkkitauluAB (
tauluAId int,
tauluBId int,
vuosi int
)
Linkkitauluun pitää sitten lisätä vuodesta riippuen oikeat arvot.

Yksi vaihtoehto on kopioida tarvittavat tiedot ajalla jne höystettynä erilliseen varastorakenteeseen josta otetaan tilastot.
 
Liittynyt
23.10.2016
Viestejä
658
En täysin ymmärrä kysymystä, mutta eikö riitä että lisäät toiseen tai tarvittaessa molempiin tauluihin kentän vuosi, jos data ei voi jostain syystä olla yhdessä taulussa, mikä olisi varmaan sen yksinkertaisin vaihtoehto.

Jos taas teet joinin taulujen välillä samalla id:llä, niin samassa taulussa voi olla sama "id" eri vuosillakin eli eri riveinä. Tosin id-kenttä ei voi olla silloin uniikki toisessa taulussa, mutta onhan tuossa jo esim. tuo "taulun id" kenttä, mitä voi käyttää joiniin. Id:t on tapana pitää uniikkeina tauluissa.
Jees, tämä tuntuu helpolta ratkaisulta. Tulee tallennettua tietokantaa turhaa tietoa, koska noita muuttuvia kenttiä ei ole montaa, mutta ei ole toisaalta noita rivejäkään.
 
Liittynyt
19.10.2016
Viestejä
12
Yritän opiskella Moocista tuota web-palvelinohjelmointia (Web-palvelimen toiminta - Web-palvelinohjelmointi Java 2020), mutta näköjään hukassa heti alkuun.

Kyseessä tuo Hello server-tehtävä.

Jos luon palvelimen näin esimerkin mukaan:

Koodi:
// luodaan palvelin porttiin 8080
ServerSocket server = new ServerSocket(8080);

while (true) {
    // odotetaan pyyntöä
    Socket socket = server.accept();

    // luetaan pyyntö
    Scanner lukija = new Scanner(socket.getInputStream());
    // ...

   // kirjoitetaan vastaus
    PrintWriter kirjoittaja = new PrintWriter(socket.getOutputStream());
    // ...
Ja tehtävän annossa on maininta: "Jos pyydetty polku on /quit, tulee palvelin sammuttaa."

Niin mistä löydän tuon polun?
 
Liittynyt
17.10.2016
Viestejä
4 589
Yritän opiskella Moocista tuota web-palvelinohjelmointia (Web-palvelimen toiminta - Web-palvelinohjelmointi Java 2020), mutta näköjään hukassa heti alkuun.

Kyseessä tuo Hello server-tehtävä.

Jos luon palvelimen näin esimerkin mukaan:

Koodi:
// luodaan palvelin porttiin 8080
ServerSocket server = new ServerSocket(8080);

while (true) {
    // odotetaan pyyntöä
    Socket socket = server.accept();

    // luetaan pyyntö
    Scanner lukija = new Scanner(socket.getInputStream());
    // ...

   // kirjoitetaan vastaus
    PrintWriter kirjoittaja = new PrintWriter(socket.getOutputStream());
    // ...
Ja tehtävän annossa on maininta: "Jos pyydetty polku on /quit, tulee palvelin sammuttaa."

Niin mistä löydän tuon polun?
Sillä varmaan viitataan siihen HTTP-pyyntöön. Eli jos pyyntö on
Koodi:
GET /quit HTTP/1.1
palvelin pitää sammuttaa.

Tuo esimerkkikoodi ei vielä luo HTTP-palvelinta - siitä puuttuu keskusteluprotokolla.
 
Liittynyt
18.10.2016
Viestejä
69
Yritän opiskella Moocista tuota web-palvelinohjelmointia (Web-palvelimen toiminta - Web-palvelinohjelmointi Java 2020), mutta näköjään hukassa heti alkuun.

Kyseessä tuo Hello server-tehtävä.

Jos luon palvelimen näin esimerkin mukaan:

Koodi:
// luodaan palvelin porttiin 8080
ServerSocket server = new ServerSocket(8080);

while (true) {
    // odotetaan pyyntöä
    Socket socket = server.accept();

    // luetaan pyyntö
    Scanner lukija = new Scanner(socket.getInputStream());
    // ...

   // kirjoitetaan vastaus
    PrintWriter kirjoittaja = new PrintWriter(socket.getOutputStream());
    // ...
Ja tehtävän annossa on maininta: "Jos pyydetty polku on /quit, tulee palvelin sammuttaa."

Niin mistä löydän tuon polun?
Se pyyntöhän luetaan tuolla Scannerilla, niin voit katsoa sieltä mitä polkua on pyydetty.
 
Liittynyt
19.10.2016
Viestejä
12
Kiitos vastanneille.
Näköjään sillä on eroa, että luetaanko System.out.println(lukija); vai System.out.println(lukija.nextLine());
 
Liittynyt
14.12.2016
Viestejä
1 297
Ensimmäinen rivi tulostaa objektin (lukija, jonka metodeita tuskin on ylikirjoitettu tulostamaan mitään järkevää muistipaikan sijaan), jälkimmäisessä kutsutaan objektin metodia (nextline) joka oletettavasti palauttaa (return) jonkun (muuttujan) arvon joka sitten tulostetaan. Luin vain edellisen viestin ketjusta.
 
Liittynyt
23.10.2016
Viestejä
658
Jos taulujen A ja B sisältö ei muuten muutu ajan mukaan (siis vuodesta/kuukaudesta/päivästä/jne riippuen) muuten kuin tuo viittaus B->A niin voit tehdä taulujen välille linkin jossa on vuosi.

Koodi:
TauluA (
id Int,
name String
)

TauluB (
id Int,
name String
)

LinkkitauluAB (
tauluAId int,
tauluBId int,
vuosi int
)
Linkkitauluun pitää sitten lisätä vuodesta riippuen oikeat arvot.

Yksi vaihtoehto on kopioida tarvittavat tiedot ajalla jne höystettynä erilliseen varastorakenteeseen josta otetaan tilastot.
Mietin tätä nyt vähän pidemmälle ja vaikuttaa siltä, että jonkinlainen linkkitaulu olisi hyvä olla. Jos nyt ymmärsin tämän oikein niin jos haluan tehdä TauluB:n tiedot sisältävän kyselyn TauluA:sta, niin tähän tarvitaan kaksi joinia: Ekalla joinilla joinataan linkkitauluAB TauluA:n kanssa ja toisella linkkitauluAB TauluB:n kanssa.

Tyyliin näin:

SQL:
SELECT
    "TauluA"."id", "TauluA.name", "LinkkitauluAB"."vuosi", "TauluB"."id", "TauluB"."name"
FROM
    "TauluA"
    INNER JOIN "LinkkitauluAB" ON "TauluA"."id" = "LinkkitauluAB"."tauluAId"
    INNER JOIN "TauluB" ON "LinkkitauluAB"."tauluBId" = "TauluB"."id"
WHERE
    "linkkitauluAB"."vuosi" = 2021
En tuosta syntaksista ole ihan varma, mutta meneekö tuo periaatteellisesti oikein?
 
Liittynyt
16.11.2020
Viestejä
2 565
Ymmärränköhän minäkään nyt ihan kaikkea tuosta kyssäristä, mutta siis jos taulu B viittaa taulun A johonkin riviin taulun A id:n perusteella, niin eikö taulussa A pitäisi olla silloin ylimääräisenä sarakkeena vuosi ja uniikit id:t eri vuosien riveille?

Jotenkin kuulostaa kovin hankalalta tuollaiset joinit ja linkkitaulut. Kuin myös natiivin SQL:n kirjoittelu koodissa näin tietämättä tarkemmin, mitä tässä toteutuksessa tehdään :) Sit jos tämän on tarkoituskin olla jonkinlainen SQL-harjoitus, niin asia eri.
 
Liittynyt
23.10.2016
Viestejä
658
Ymmärränköhän minäkään nyt ihan kaikkea tuosta kyssäristä, mutta siis jos taulu B viittaa taulun A johonkin riviin taulun A id:n perusteella, niin eikö taulussa A pitäisi olla silloin ylimääräisenä sarakkeena vuosi ja uniikit id:t eri vuosien riveille?

Jotenkin kuulostaa kovin hankalalta tuollaiset joinit ja linkkitaulut. Kuin myös natiivin SQL:n kirjoittelu koodissa näin tietämättä tarkemmin, mitä tässä toteutuksessa tehdään :) Sit jos tämän on tarkoituskin olla jonkinlainen SQL-harjoitus, niin asia eri.
Joo harjoituksen vuoksi pohdin näitä. Ehkä käytännön esimerkki auttaa ymmärtämään kysymyksen paremmin.

Koitetaan vaikka käyttää kauppojen ja tuotteiden suhteita. Leikitään, että kaupoissa myydään tiettyjä tuotteita jonkin ajanjakson ajan ja jokaista tuotetta myydään kerrallaan vain yhdessä kaupassa. Eli esimerkiksi mulla on:
Koodi:
Kauppa
    id Int
    nimi String
    myynnissäOlevatTuotteet Tuote[]
    
Tuote
    id Int
    nimi String
    myynnissäKaupassa Kauppa
Tuo oli mun alkuperäinen toteutus. Ongelma on se, että jos päivitän jonkin tuotteen myynnissäKaupassa-kentän, niin siitä ei jää mitään historiatietoja.

Yksi potentiaalinen ratkaisu voisi olla ajanjakson lisääminen tuotteisiin näin:
Koodi:
Tuote
    id Int
    luontiaika DateTime
    päättymisaika DateTime
    nimi String
    myynnissäKaupassa Kauppa
Näin tekemällä tietäisin aina missä kaupassa tuote on ollut myynnissä minäkin ajanhetkenä. Tässä tulee ongelmaksi se, että tuotteissa on kauppojen lisäksi muitakin riippuvuuksia, jotka taas ei riipu ajanhetkestä. Tässä esimerkissä riippuvuus voisi olla vaikka asiakas:

Koodi:
Tuote
    id Int
    luontiaika DateTime
    päättymisaika DateTime
    nimi String
    myynnissäKaupassa Kauppa
    myytyAsiakkaille Asiakas[]

Asiakas
    id Int
    nimi String
    ostetutTuotteet Tuote[]
Jos tässä tilanteessa haluan löytää Tuote-taulun kautta keille asiakkaille tuotetta on myyty kaupasta ja ajankohdasta riippumatta, niin kyselystä tulee monimutkaisempi, koska ensin täytyy yhdistää eri id:llä esiintyvät kuitenkin samat tuotteet "yhdeksi" ja sitten vasta hakea ne asiakastiedot.

Toivottavasti tämä selitys vähän selventää ongelmaa.
 
Liittynyt
17.10.2016
Viestejä
4 589
Jos tässä tilanteessa haluan löytää Tuote-taulun kautta keille asiakkaille tuotetta on myyty kaupasta ja ajankohdasta riippumatta, niin kyselystä tulee monimutkaisempi, koska ensin täytyy yhdistää eri id:llä esiintyvät kuitenkin samat tuotteet "yhdeksi" ja sitten vasta hakea ne asiakastiedot.
No tämähän on ihan klassinen many-to-many -relaatio tuotteiden ja kauppojen välillä. Se ratkeaa juuri linkitystaulun avulla, esim:

Koodi:
TuoteKauppa
    tuoteId
    kauppaId
    myynnissäAlk
    myynnissäPäät
 
Liittynyt
16.11.2020
Viestejä
2 565
Meikäläisen leipätyötä ei oo miettiä tietokantarakenteita, enkä väitä olevani mikään kova ammattilainen tietokantahommissa, mutta mietin tuossa jo aikaisemmin, että onko relaatiokanta oikea valinta tällaisille rakenteille.. Eikö esim. yhden sarakkeen arvon tule olla relaatiokannassa oppikirjamaisesti yksikäsitteinen? Nythän tuolla on sarakkeiden arvoina listoja, jotka nyt tietysti voi toteuttaa kooditasolla vaikka erotinmerkeillä varustettuina Stringeinä, mutta se ei liene oikein hyvää tapaa relaatiokantojen kanssa..

Ja jotenkin mulle tulis ekana mieleen käyttää jotain dokumenttitietokantaa tällaisessa, mutta en tokikaan kerennyt hirveästi pureskelemaan tämän tarvetta, kun tässä palaverin sivussa kirjoittelen :D

muoks. tai vaikka ei sotke tähän mitään dokumenttitietokantoja, niin voisi ainakin miettiä sitä, mikä tuollaisen kannan rakenne tulisi oikeasti olla.
 
Viimeksi muokattu:
Liittynyt
17.10.2016
Viestejä
4 589
Meikäläisen leipätyötä ei oo miettiä tietokantarakenteita, enkä väitä olevani mikään kova ammattilainen tietokantahommissa, mutta mietin tuossa jo aikaisemmin, että onko relaatiokanta oikea valinta tällaisille rakenteille.. Eikö esim. yhden sarakkeen arvon tule olla relaatiokannassa oppikirjamaisesti yksikäsitteinen? Nythän tuolla on sarakkeiden arvoina listoja, jotka nyt tietysti voi toteuttaa kooditasolla vaikka erotinmerkeillä varustettuina Stringeinä, mutta se ei liene oikein hyvää tapaa relaatiokantojen kanssa..

Ja jotenkin mulle tulis ekana mieleen käyttää jotain dokumenttitietokantaa tällaisessa, mutta en tokikaan kerennyt hirveästi pureskelemaan tämän tarvetta, kun tässä palaverin sivussa kirjoittelen :D

muoks. tai vaikka ei sotke tähän mitään dokumenttitietokantoja, niin voisi ainakin miettiä sitä, mikä tuollaisen kannan rakenne tulisi oikeasti olla.
Joo, en edes lukenut niin tarkkaan että olisin nohin taulukoihin kiinnittänyt huomiota. Ei tosiaan ole normalisoitu rakenne tuo.

Pitäisi esim. olla erikseen asiakkaat -- tilaukset -- tilausTuote -linkitys.
 
Liittynyt
03.07.2018
Viestejä
347
Miten php:ssa voisi tehdä curl-kutsun samalle palvelimelle ja samaan kansioon mutta eri tiedostoon ?

Tällä olisi tarkoitus saavuttaa:
- Kutsua toista skriptiä ilman että pääskriptin suoritus mitenkään häiriytyy tai keskeytyy vaikka kohdeskriptissä olisi mitä tahansa server 500 aiheuttavia virheitä
- onnistuuhan tuo nytkin kun laittaa curliin koko urlin, alkaen https.., mutta mitä jos palvelimen osoitetta ja alikansiota ei löydy mistään envifilusta tms. eli kutsu pitäisi olla tyyliin call('skirpti2.php);

onko tähän esim. jotain erikoista include-komentoa vastaavaa ?
 
Liittynyt
17.01.2018
Viestejä
1 997
Kannattaa unohtaa listat jos tekee relaatiokannalla. Käytännössä listat muutetaan silloin riveiksi, yleensä omaan tauluun.

Esimerkkinä voisi olla vaikka näin (sivuttiin jo tuossa ylempanä)
Koodi:
Tuote (
    id,
    nimi
)

Kauppa (
    id,
    nimi
)

Asiakas (
    id,
    nimi,
    email
)

Myynnissä (
    kauppa_id,
    tuote_id,
    alkupvm,
    loppupvm
)

Ostetut (
    kauppa_id,
    asiakas_id,
    tuote_id
)
Kannan mallista riippuen data pitää mallintaa oikeaan muotoon, relaation tapauksessa tulee useita tauluja.

Se onko jokin sarake/tieto uniikki kannassa vai ei riippuu tarkoituksesta. Esimerkkinä jos voidaan poistaa tuotteita. Poistettujen pitää todennäköisesti silti näkyä asiakkaiden ostoshistoriassa/muualla niin silloin tietoja pitää kopioida tai vaihtoehtoisesti vain piilottaa näkyvistä jossain.

Tuosta esimerkistä saisi listan:
Koodi:
select <halutut sarakkeet>
from tuote t, ostetut o, asiakas a, kauppa k
where t.id = o.tuote_id
and o.asiakas_id = a.id
and o.kauppa_id = k.id
Ja järjestämällä/rajaamalla tuotteella/asiakkaalla/kaupalla se vastaa esimerkiksi kysymyksiin "tuotetta x ostivat asiakkaat y kaupoista z" tai "asiakas x osti tuotteet y kaupoista z" jne.

Kummassakin tapauksessa avainnus on tärkeää että löydetään oikeat rivit joka paikasta.

Hyvä periaate on se että tauluun ei laiteta sellaista tietoa joka monistaa rivejä, esimerkiksi tuotetauluun ei saa laittaa kauppaa koska silloin yksi tuote voi olla myynnissä vain yhdessä kaupassa. Sama koskee myynnin voimassaoloaikaa, se on tuote-kauppa- kohtainen.
Luontiaika ja muutosaika tuotteella voi olla.
 
Liittynyt
23.10.2016
Viestejä
658
Se sitä hain tuolla linkkitauluAB-esimerkilläni oli juuri tuo Zighin esittämä many-to-many-relaatio. Minulla oli siis päässäni jonkinlainen ratkaisu valmiina, mutta en tiennyt, että oliko se "oikea" tapa hoitaa homma.

Kannattaa unohtaa listat jos tekee relaatiokannalla. Käytännössä listat muutetaan silloin riveiksi, yleensä omaan tauluun.
Juu en osaa esittää oikein mitä ajan takaa. Hakasulkeilla en tarkoittanut listaa vaan koitin ilmaista, että kenttä sisältää useampia relaatioita (one-to-many-relaation one-puoli). Tämä syntaksi on käytössä ORMissa, jota käytän.

Hyvä periaate on se että tauluun ei laiteta sellaista tietoa joka monistaa rivejä, esimerkiksi tuotetauluun ei saa laittaa kauppaa koska silloin yksi tuote voi olla myynnissä vain yhdessä kaupassa. Sama koskee myynnin voimassaoloaikaa, se on tuote-kauppa- kohtainen.
Luontiaika ja muutosaika tuotteella voi olla.
Joo tämän takia aloin miettimään parempaa ratkaisua. Joku ehdotti vuoden (alkuperäissä esimerkissä puhuttiin vuosista) tallentamista suoraan esimerkiksi tuote-tauluun, mutta se olisi aiheuttanut ongelmia duplikaattidatan ja monimutkaisempien kyselyjen muodossa.

Koodi:
select <halutut sarakkeet>
from tuote t, ostetut o, asiakas a, kauppa k
where t.id = o.tuote_id
and o.asiakas_id = a.id
and o.kauppa_id = k.id
En tiennytkään, että dataa voi valita selektiä käyttämällä useammasta taulukosta ilman joinia.
 
Liittynyt
17.01.2018
Viestejä
1 997
Se sitä hain tuolla linkkitauluAB-esimerkilläni oli juuri tuo Zighin esittämä many-to-many-relaatio. Minulla oli siis päässäni jonkinlainen ratkaisu valmiina, mutta en tiennyt, että oliko se "oikea" tapa hoitaa homma.



Juu en osaa esittää oikein mitä ajan takaa. Hakasulkeilla en tarkoittanut listaa vaan koitin ilmaista, että kenttä sisältää useampia relaatioita (one-to-many-relaation one-puoli). Tämä syntaksi on käytössä ORMissa, jota käytän.


Joo tämän takia aloin miettimään parempaa ratkaisua. Joku ehdotti vuoden (alkuperäissä esimerkissä puhuttiin vuosista) tallentamista suoraan esimerkiksi tuote-tauluun, mutta se olisi aiheuttanut ongelmia duplikaattidatan ja monimutkaisempien kyselyjen muodossa.

Koodi:
select <halutut sarakkeet>
from tuote t, ostetut o, asiakas a, kauppa k
where t.id = o.tuote_id
and o.asiakas_id = a.id
and o.kauppa_id = k.id
En tiennytkään, että dataa voi valita selektiä käyttämällä useammasta taulukosta ilman joinia.
Onhan tuossa join joka taulun välissä, syntaksi on vaan eri.

Select *
from a join b on a.i = b.i
where a.x = 1

Select *
from a, b
where a.i = b.i
and a.x = 1

Näissä toiminnallisuus on sama eri syntaksilla, ei ole väliä kumpaa käyttää paitsi jos mukana on outer join, silloin pitää olla tarkkana missä ehdot määritetään.
 

Starglazer

Tukijäsen
Liittynyt
17.10.2016
Viestejä
3 092
Onhan tuossa join joka taulun välissä, syntaksi on vaan eri.
Select *
from a join b on a.i = b.i
where a.x = 1

Select *
from a, b
where a.i = b.i
and a.x = 1

Näissä toiminnallisuus on sama eri syntaksilla, ei ole väliä kumpaa käyttää paitsi jos mukana on outer join, silloin pitää olla tarkkana missä ehdot määritetään.
Lievä ot, minä kirjoitan SQL:n nykyään näin:
Koodi:
select
   *
from
   a
   , b
where
    a.i = b.i
    and ax = 1
Näin saa helposti kommentoitua rivit mitä ei sillä hetkellä tarvitse.
E: Ja nykyään olen opetellut käyttämään taulujen liitokseen from joinia. Se on osin selkeämpi jos tauluja on paljon ja että liitos tulee varmasti oikein eikä jää where lauseessa tekemättä.
 
Viimeksi muokattu:
Liittynyt
17.01.2018
Viestejä
1 997
Lievä ot, minä kirjoitan SQL:n nykyään näin:
Koodi:
select
   *
from
   a
   , b
where
    a.i = b.i
    and ax = 1
Näin saa helposti kommentoitua rivit mitä ei sillä hetkellä tarvitse.
E: Ja nykyään olen opetellut käyttämään taulujen liitokseen from joinia. Se on osin selkeämpi jos tauluja on paljon ja että liitos tulee varmasti oikein eikä jää where lauseessa tekemättä.
Joo, normaalisti en myöskään kirjoita noin mutta puhelimella kirjoitettaessa ei aina jaksa säätää muotoilun kanssa.

Tämä(kin) asia on varmaan sellainen jossa monilla on oma mielipide siitä mikä on hyvä ja mikä huono tapa kirjoittaa.
Ja toisaalta kun on aloittanut sql:n kirjoituksen reilu 20 vuotta sitten niin helposti palaa alkupään syntaksiin...
 
Liittynyt
07.01.2017
Viestejä
693
Saattaa olla turha kysymys, mutta eikö tosiaan php:hen ole tullut CVE -ilmoituksia vuonna 2020 ja 2021 ollenkaan? Vain onkohan joku hakuehto nyt väärin itsellä..
 
Liittynyt
19.10.2016
Viestejä
3 411
Olen jokseenkin varma, että törmäsin joskus sivustoon, jossa kuvattiin miten o365 (Word) dokkari luotiin (ja ehkäpä jaettiin muidenkin käyttöön) omalta weppisivulta. Onko tämä nykyisin mahdollista (o365 tilaus editoijilla)? Varmaan nopealla haulla etsin huonoilla hakutermeillä, mutta löysin vain embeddauksen, (noh, jonkun worksheet api-kutsunkin, mutta en mitään wordista). Word-addinit näytti sotkevan hakutuloksien relevanttiutta.

Google docsille löysin apin, ainakin nopeasti kurkattuna näyttää lupaavammalta. Olenko oikeassa, että ainakin Google Docsissa onnistuu?

eli haluttu toiminnallisuus:
  1. kirjautunut käyttäjä painaa nappia luo dokumentti
  2. dokumentille asetetaan luku/muokkausoikeudet (ennalta määritellyille käyttäjille/ryhmille)
  3. Muut edellisen listan käyttäjät pääsevät lukemaan / editoimaan dokkaria
 
Liittynyt
23.10.2016
Viestejä
658
SQL-linjalla jatketaan. Mulla on tämä kysely:

SQL:
SELECT "Player"."id", "Player"."lastName", SUM("GameStats"."goals") AS "goals"
FROM "Player"
INNER JOIN "GameStats" ON "Player"."id" = "GameStats"."playerId"
GROUP BY "Player"."id";
Eli tuo kysely hakee kannasta kaikki pelaajat, joinaa pelaajatiedot pelikohtaisten tilastojen kanssa, summaa peleissä tehdyt maalit ja ryhmittää pelaajien mukaan. Mitäs jos en halua ottaa huomioon kaikkia pelejä vaan esimerkiksi vain 5 viimeisintä peliä? Oma veikkaus on, että tuon joinin jälkeen tarvitsisi jonkun WHERE-lausekkeen, mutta en keksi miten määritän ehdoksi "viisi viimeisintä riviä".
 
Liittynyt
17.01.2018
Viestejä
1 997
SQL-linjalla jatketaan. Mulla on tämä kysely:

SQL:
SELECT "Player"."id", "Player"."lastName", SUM("GameStats"."goals") AS "goals"
FROM "Player"
INNER JOIN "GameStats" ON "Player"."id" = "GameStats"."playerId"
GROUP BY "Player"."id";
Eli tuo kysely hakee kannasta kaikki pelaajat, joinaa pelaajatiedot pelikohtaisten tilastojen kanssa, summaa peleissä tehdyt maalit ja ryhmittää pelaajien mukaan. Mitäs jos en halua ottaa huomioon kaikkia pelejä vaan esimerkiksi vain 5 viimeisintä peliä? Oma veikkaus on, että tuon joinin jälkeen tarvitsisi jonkun WHERE-lausekkeen, mutta en keksi miten määritän ehdoksi "viisi viimeisintä riviä".
Millä perusteella haluat 5 viimeistä ?
Id- sekvenssi jonka mukaan otetaan 5 suurinta / aikaleima joista 5 viimeisintä / joku muu ?

Ja sitten vielä tärkeä, mikä kanta on alla ?
 
Liittynyt
23.10.2016
Viestejä
658
Millä perusteella haluat 5 viimeistä ?
Id- sekvenssi jonka mukaan otetaan 5 suurinta / aikaleima joista 5 viimeisintä / joku muu ?

Ja sitten vielä tärkeä, mikä kanta on alla ?
PostgreSQL-kanta.

Tosiaan, tuossa GameStats-taulukossa mulla ei ole suoraan tarvittavaa järjestystietoa. Mun pitäisi GameStats taulukko joinata ensin Game-taulukkoon, josta löytyy gameDate-tieto. Tuon gameDaten perusteella tarvitsisin viisi viimeisintä riviä GameStatseista.
 
Liittynyt
17.01.2018
Viestejä
1 997
PostgreSQL-kanta.

Tosiaan, tuossa GameStats-taulukossa mulla ei ole suoraan tarvittavaa järjestystietoa. Mun pitäisi GameStats taulukko joinata ensin Game-taulukkoon, josta löytyy gameDate-tieto. Tuon gameDaten perusteella tarvitsisin viisi viimeisintä riviä GameStatseista.
En testannut mutta tähän tyyliin pitäisi onnistua

Koodi:
SELECT
    Player.id,
    Player.lastName,
    SUM(stats.goals) AS goals
FROM
    Player INNER JOIN
    (
            SELECT
                GameStats.playerId AS playerId,
                GameStats.goals AS goals,
                ROW_NUMBER() OVER (PARTITION BY GameStats.playerId ORDER BY Game.gameDate DESC) AS seqnum
            FROM
            Game JOIN GameStats ON (
                Game.id = GameStats.gameId
            )
    ) stats ON (
        Player.id = stats.playerId
    )
WHERE
    stats.seqnum < 6
GROUP BY
    Player.id,
    Player.lastName
Pikaselitys:
Sisemmässä kyselyssä haetaan playerid + goals ja samalla tehdään ikkun ointifunktiolla kasvava järjestysnumero per playerid.
Ulommassa ulommassa kyselyssä yhdistetään sisemmän tulokseen player (= rivimäärä ei muutu) ja rajataan ikkunoinnin luoma rivinumero < 6 ja summataan goals.

Testaa kannassa ensin sisempi erikseen että saat oikeanlaisen tuloksen ja sen jälkeen yhdistelmä.
 
Liittynyt
23.10.2016
Viestejä
658
En testannut mutta tähän tyyliin pitäisi onnistua

Koodi:
SELECT
    Player.id,
    Player.lastName,
    SUM(stats.goals) AS goals
FROM
    Player INNER JOIN
    (
            SELECT
                GameStats.playerId AS playerId,
                GameStats.goals AS goals,
                ROW_NUMBER() OVER (PARTITION BY GameStats.playerId ORDER BY Game.gameDate DESC) AS seqnum
            FROM
            Game JOIN GameStats ON (
                Game.id = GameStats.gameId
            )
    ) stats ON (
        Player.id = stats.playerId
    )
WHERE
    stats.seqnum < 6
GROUP BY
    Player.id,
    Player.lastName
Pikaselitys:
Sisemmässä kyselyssä haetaan playerid + goals ja samalla tehdään ikkun ointifunktiolla kasvava järjestysnumero per playerid.
Ulommassa ulommassa kyselyssä yhdistetään sisemmän tulokseen player (= rivimäärä ei muutu) ja rajataan ikkunoinnin luoma rivinumero < 6 ja summataan goals.

Testaa kannassa ensin sisempi erikseen että saat oikeanlaisen tuloksen ja sen jälkeen yhdistelmä.
Kiitos! Toimii nätisti. Vähän vaikea ymmärtää amatöörille, mutta pala kerrallaan menee perille.

Itse pääsin omin päin tähän asti:
SQL:
SELECT "CumulativeStats"."id" AS "playerId", "CumulativeStats"."lastName", SUM(goals) AS "goals" FROM (
    SELECT "Player"."id", "Player"."lastName", "Game"."gameDate", "GameStats"."goals"
    FROM "Player"
    INNER JOIN "GameStats" ON "Player"."id" = "GameStats"."playerId"
    INNER JOIN "Game" ON "GameStats"."gameId" = "Game"."id"
) AS "CumulativeStats"
GROUP BY "playerId", "lastName";
Tuosta tosiaan puuttuu juuri se tärkein eli miten ottaa huomioon vain 5 viimeisintä peliä.
 
Liittynyt
17.01.2018
Viestejä
1 997
Kiitos! Toimii nätisti. Vähän vaikea ymmärtää amatöörille, mutta pala kerrallaan menee perille.

Itse pääsin omin päin tähän asti:
SQL:
SELECT "CumulativeStats"."id" AS "playerId", "CumulativeStats"."lastName", SUM(goals) AS "goals" FROM (
    SELECT "Player"."id", "Player"."lastName", "Game"."gameDate", "GameStats"."goals"
    FROM "Player"
    INNER JOIN "GameStats" ON "Player"."id" = "GameStats"."playerId"
    INNER JOIN "Game" ON "GameStats"."gameId" = "Game"."id"
) AS "CumulativeStats"
GROUP BY "playerId", "lastName";
Tuosta tosiaan puuttuu juuri se tärkein eli miten ottaa huomioon vain 5 viimeisintä peliä.
X ensimmäistä/viimeisintä avainsana on ikkunointi tai rank.
Näköjään tuurilla meni sitten oikein kun en testannut mitenkään. Välillä niinkin päin.
 
Liittynyt
23.10.2016
Viestejä
658
Lisäsin tuohon vielä jokaiselle riville pelaajan nykyisen tiimin nimen. Hakuaikaa tuli yli tuplat lisää. Meniköhän joku väärin? Ilman tiimiä hakuaika on 0,5s ja tiimin kanssa 1,3s.

Tässä ratkaisuni:
SQL:
          SELECT
          "Player"."id",
          "Team"."name",
          SUM("Stats"."goals") AS "goals",
          SUM("Stats"."assists") AS "assists"
          FROM
          "Player" INNER JOIN
          (
                  SELECT
                      "GameStats"."playerId" AS "playerId",
                      "GameStats"."goals" AS "goals",
                      "GameStats"."assists" AS "assists",
                      ROW_NUMBER() OVER (PARTITION BY "GameStats"."playerId" ORDER BY "Game"."gameDate" DESC) AS "seqnum"
                  FROM
                  "Game" JOIN "GameStats" ON (
                      "Game"."id" = "GameStats"."gameId"
                  )
          ) "Stats" ON (
              "Player"."id" = "Stats"."playerId"
          )
            JOIN "PlayerTeam" ON "Player"."id" = "PlayerTeam"."playerId"
            JOIN "Team" ON "PlayerTeam"."teamId" = "Team"."id"
            WHERE
            "Stats"."seqnum" < 6 AND
            "PlayerTeam"."endDate" IS NOT NULL
            GROUP BY
            "Player"."id",
            "Team"."name"
Mulla on siis PlayerTeam-niminen taulukko, jossa on viittauksen kaikkiin pelaajien aikaisempiin tiimeihin ja nykyinen tiimi on se rivi, jossa endDate on NULL. Tässä on sellainen ongelma, että nyt käsittääkseni jokaisen pelaajan tilastot jakautuu joukkueiden mukaan, mutta tämä ei ole haluttua. Haluaisin tehdä niin, että GROUP BY:ssä lasketaan kaikki tilastot tiettyjen pelien osalta yhteen ja vasta sen jälkeen lisätään hakutulokseen muu "metadata", kuten esimerkiksi juuri tuo tiimi ja kaikki muu Player-taulukosta löytyvä data.
 
Viimeksi muokattu:
Liittynyt
27.03.2017
Viestejä
2 736
Olen C# aloittelija. Miksi en löydä projektista (vai solutionista?) tiettyä muuttujaa Visual Studio 2019 Community:llä?

Tarkoitukseni oli muuttaa muuttujan VeryLow.DistanceFromTakeOffLocation arvo käsin:
1. Kloonasin suoraan VS2019:llä
2. Avasin VS2019:llä Source/BriefingRoom.sln (kokeilin myös Source/BriefingRoom.csproj)
3. Ctrl+f ja hakukenttään VeryLow.DistanceFromTakeOffLocation
4. Ei löydy!?

Hämmentyneenä etsin sen sitten käsin ja se löytyi Database/Objectives.ini:stä. Miksi VS2019 ei etsinyt myös tuolta Database-hakemistosta? Sitä ei tosin näy VS:n puolella Solution Explorerissa, eli nuin kai sen pitäisikin toimia, mutta hämää paljon kun se silti tuli gitistä samaan syssyyn ja lukeehan se ohjelmakin tuota tiedostoa!?
 
Toggle Sidebar

Statistiikka

Viestiketjut
237 401
Viestejä
4 159 819
Jäsenet
70 408
Uusin jäsen
allun90

Hinta.fi

Ylös Bottom