Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: SQL: riviparien aikaleimojen erotus

Sivun loppuun

Rytkonen [21.05.2008 11:11:43]

#

Morjens!

Tiedän, todella huono otsikko, mutta mennään asiaan.

Näin alkuun voin sanoa, että olen aikamoinen ummikko näiden sql-systeemien kanssa. Ymmärrän kyllä suurin piirtein noiden kyselyiden rakennetta, mutta yhtäkään varsinaista kyselyä en ole ikinä tehnyt.

Työpaikallani on Sql-serverillä tietokanta, jossa on taulu (puhelinmyynti jne alan firma) johon tallentuu tiedot eräistä puheluista. Minun pitäisi tehdä jonkinlainen kysely (tai joku tallennettu proseduuri tms.), joka etsii taulusta puhelut joissa on erään kentän arvona "T" ja tämän jälkeen etsii seuraavan puhelun taulusta jossa on myös eräässä kohdassa "T". Näitä puheluita sitten pitäisi pystyä vertailemaan, esimerkiksi alku- ja loppuajankohdat.

Kuinka tällainen olisi paras toteuttaa, pitäisikö tehdä joku tallennettu proseduuri (stored procedure) vai mikä?

Toivottavasti joku ymmärsi mitä tässä haetaan ja osaisi antaa jotain suuntaa antavia neuvoja!

Terveisin,

Aleksi

Metabolix [21.05.2008 11:55:23]

#

En aivan ymmärtänyt, mutta tässä olisi hyvä lähtökohta:
SELECT * FROM puhelutaulu WHERE kentta = 'T';
Tai vain halutut tiedot: SELECT alku, loppu FROM puhelutaulu WHERE kentta = 'T';

Mitä nyt oikeastaan piti vertailla ja mihin, ja kuka vertailun suorittaa? Onko tarkoitus vain saada tiedot sellaiseen muotoon, että joku voi niitä käsin vertailla, vai pitäisikö vertailu jotenkin suorittaa tietokoneella? Mitä pitäisi saada tulokseksi?

Rytkonen [21.05.2008 12:01:48]

#

Hyviä kysymyksiä! Eli pitäisi etsiä taulusta rivi, joiden tietyssä kentässä on tuo "T". Kun se on löydetty, mennään eteenpäin taulussa ja etsitään seuraavaksi rivi jossa on sitten tämä samainen "T" tietyssä kentässä.

Näitä kahta riviä pitäisi sitten vertailla. Kyse on aikojen välisestä erosta, joten jos se on mahdollista, eron voisi palauttaa takaisin ohjelmaan (ms reporting services). Eli tyyliin: aikaero = rivi1.aika - rivi2.aika

Pirun hankala selittää tätä kun en ole yhtään perehtynyt tähän sql-tekniikkaan. Kyselkää lisää.

Metabolix [21.05.2008 12:30:25]

#

Kokeillaanpa. Suunnilleen tällainen kysely toimi ainakin MySQL:n puolella.

SELECT
  alku AS 'alku1',
  ((
    SELECT
      alku
    FROM
      puhelut
    WHERE
      kentta = 'T'
      AND alku > alku1
    ORDER BY alku
    LIMIT 1
   ) - alku
  ) AS alkuero
FROM
  puhelut
WHERE
  kentta = 'T';

Loogisesti kai jokseenkin näin, eli haetaan taulusta puhelun alku ja alikyselyssä yhden tätä myöhemmin alkavan puhelun alku. Kysely nyt olettaa, ettei kaksi puhelua voi alkaa samaan aikaan, tarkemmassa erottelussa voi tietenkin käyttää jotain muuta kenttää. On luultavasti järkevää tehdä kelpaavista puheluista (kentta = 'T') ensin näkymä (VIEW), jotta säästyy pari ehtoriviä itse kyselystä.

Tulkoon joku viisaampi kertomaan kyselyyn järkevämmän tavan. :)

Rytkonen [21.05.2008 14:41:57]

#

En saanut tuota toimimaan ainakaan vielä, käytössä on siis sql server 2005. Sen verran itse opiskelin tuota sql querya, että sain sentään tulostettua nuo rivit joilla on tuo maaginen "T" kirjain.

Tarkennetaan vielä että menee varmasti sekavaksi. :D

Taulusta tulisi siis etsiä ensin rivi jossa on kenttä1:ssä tuo arvo "T". Tällä rivillä on omalla kentällään eräänlainen id-numeron tapainen. Tämän jälkeen etsitään sille kaveriksi rivi2, jolla on kenttä2:ssa tuo "T" ja verrataan tällä rivi2:lla olevaa numeroa rivi1:n vastaavaan. Jos numerot ovat samat, lasketaan rivien aikakenttien välinen ero. Onnistuuko tämmöinen jollain tapaa? Nuo rivit ovat usein peräkkäin, mutta eivät aina! Jos joku ymmärtää mitä tässä haetaan, niin olen kiitollinen kaikesta avusta. Ja kyselkää lisää kysymyksiä!

Kiitos.

Rytkonen [22.05.2008 08:42:24]

#

Enpä saa nyt toimimaan tosiaan tuota Metabolixin kyselyä. Syntax erroria tulee? Kysely näyttää tältä:

SELECT     Aika AS 'Aika1'
((
SELECT Aika AS 'Aika2'

FROM taulu

WHERE (kentta = 'T') AND (Aika BETWEEN @pvm AND @pvm)
ORDER BY Aika2
LIMIT 1

) - Aika1
) AS Aikaero

FROM taulu
WHERE (kentta = 'T') AND (Aika BETWEEN @pvm AND @pvm)

Newb [22.05.2008 13:10:19]

#

Sulta puuttuu kaikki ;-merkit.

Metabolix [22.05.2008 13:30:11]

#

Vastaako tämä toiveitasi?

Taulu:

lukukenttaalku
1T11.00
2T11.05
1T11.08
2T11.27
3Q11.55
3Q12.15
4T12.29
4T13.37

Tulos:

lukualku1alku2ero
111.0011.080.08
211.0511.270.22
412.2913.371.08

Kysely (testaamaton, kun ei satu nyt tuollaista taulua olemaan enkä jaksa ruveta tekemään):

SELECT
  DISTINCT luku AS 'luku1',
  (SELECT alku FROM taulu WHERE luku = luku1 ORDER BY aika ASC LIMIT 1) AS 'alku1',
  (SELECT alku FROM taulu WHERE luku = luku1 ORDER BY aika DESC LIMIT 1) AS 'alku2',
  ((SELECT alku FROM taulu WHERE luku = luku1 ORDER BY aika DESC LIMIT 1) - (SELECT alku FROM taulu WHERE luku = luku1 ORDER BY aika ASC LIMIT 1)) AS 'ero'
FROM taulu
WHERE kentta = 'T';

Valitaan siis jokaista eri lukua kohden ajallisesti ensimmäinen ja viimeinen puhelu ja näiden erotus.

Valitettavasti aliaksia (alku1, alku2, sinulla Aika1) ei voi käyttää laskuissa (tai jos voi, joku saisi kertoa minullekin, miten).

Virheiden tapauksessa on usein hyvä kertoa myös, millainen virhe tulee. Mikä on tämä @pvm?

Rytkonen [22.05.2008 13:34:48]

#

Jotain tuollaista tässä haetaan. Sain tuon kyllä jollain tavalla jo toimimaan melkoisilla purkkapatenteilla. :D Täytyy kokeilla tuota ehdotustasi tässä lähiaikoina myös.

Tuo @pvm on parametri jonka käyttäjä antaa. Huomasin juuri että en ole näköjään kertonut että tätä sql kyselyä käytän siis Microsoftin reporting servicessä, josta tuo @pvm-päivämäärä parametri tulee. Kyselen varmaan aiheesta tässä lähipäivinä vielä lisää! Pahoittelen typeriä kysymyksiäni, en ole vaan koskaan tehnyt käsin noita sql-kyselyitä, joten en oikein tunne sen syntaksia ja mahdollisuuksia!

Löytyykö täältä muuten ketään, joka on työskennellyt tuon Reporting servicen kanssa?

Rytkonen [27.05.2008 15:22:50]

#

Taidanpa käyttää tätä samaa aihetta uudelle kysymykselleni.

Minulla on kaksi taulua, joissa toisessa on varsinaiset tiedot joilla on aikaleima. Toisessa taulussa on tallennettuna kellonajat puolen tunnin välein vuorokauden ajalta, näin: 00:00,00:30,01:00,01:30 jne. Onko mahdollista tehdä sql kysely, joka hakee kaikki tapahtumat esimerkiksi välillä 00:30-01:00 tuosta ensin mainitusta taulusta? Tai että tapahtumat ikäänkuin lajiteltaisiin noille puolen tunnin aikaväleille, jos ymmärrätte mitä tarkoitan?

Terveisin,

Aleksi

TsaTsaTsaa [27.05.2008 15:36:54]

#

Between lienee avainsana, eli jotenkin tähän suuntaan:

SELECT * FROM tapahtumat WHERE aika BETWEEN alkuaika AND loppuaika

Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta