Avaleht
uus teema   vasta Tarkvara »  Programmeerimine »  SQL abi märgi kõik teemad loetuks
märgi mitteloetuks
vaata eelmist teemat :: vaata järgmist teemat
mine lehele eelmine  1, 2
Hinnavaatlus :: Foorum :: Uudised :: Ärifoorumid :: HV F1 ennustusvõistlus :: Pangalink :: Telekavad :: HV toote otsing
autor
sõnum Saada viide sõbrale.  :: Teata moderaatorile teata moderaatorile
otsing:  
cannuman
HV vaatleja

liitunud: 05.06.2007




sõnum 27.07.2010 16:24:47 vasta tsitaadiga

Kuna tegelikult on dimensiooni tabeleid rohkem kui 1, siis puhtalt erinevate võtmete eritamiseks faktitabelis on nimed sisukamad kui ID.
Kommentaarid: 3 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 3
tagasi üles
vaata kasutaja infot saada privaatsõnum
2korda2
HV kasutaja

liitunud: 19.07.2003




sõnum 27.07.2010 17:26:00 vasta tsitaadiga

Kui teed viite teise tabeli PK-le, siis viitava veeru nimi on kujul TABELINIMI_VEERUNIMI (näiteks viide lepingule on LEPING_ID). PK enda nimi sisaldab ka tabeli nime (PK_LEPING). Ma ei tea, millist UML vahendit kasutad aga näiteks Enterprise Architect suudab võtmete nimetusi mõistlikul kujul automaatselt luua.
Kommentaarid: 7 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
cannuman
HV vaatleja

liitunud: 05.06.2007




sõnum 05.08.2010 13:23:11 vasta tsitaadiga

iFlop kirjutas:
cannuman, tundub, et lihtsa subquery'ga saab soovitud tulemuse. Testitud MySQL päring:
sql:
  1. SELECT test.date AS kuupäev, nimi AS name, value, (SELECT min(date) FROM test WHERE test.date < kuupäev AND name=nimi) AS 'Kehtivuse lõpp'
  2. FROM test

Kindlasti võib olla ka paremaid lahendusi, sest sql'ga ei puutu liiga tihti kokku.



Nii. Oleks vaja teha sama loogika alusel tabelile update...Ehk siis uuendada read, kus 'Kehtivuse lõpp' on NULL. Kuna päring on küllalt ajamahukas, siis eelpool näidatud viisil kogu tabel üle käia on ebasobiv lahendus.

Proovisin ise nii, aga viga koodis:



sql:
  1. UPDATE my_table
  2. SET     
  3.  
  4. date_end = SELECT
  5.  
  6.                           (SELECT     MIN(date_calc)
  7.                             FROM          my_table AS b
  8.                             WHERE      (a.date < date) AND (a.product_key = product_key) ) AS date_end
  9. FROM         my_table AS a
  10. WHERE     date_end IS NULL


Ilmselt ei saa kasutada SELECTi uue väärtusena. Oskab kegi nõu anda?
Kommentaarid: 3 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 3
tagasi üles
vaata kasutaja infot saada privaatsõnum
mikk36
HV Guru
mikk36

liitunud: 21.02.2004




sõnum 05.08.2010 13:38:57 vasta tsitaadiga

Koodi ei proovinud, kuid mu loogika ütleb et sa peaksid realt 4 eemaldama sõna select ja realt 8 eemaldama lõpust "AS date_end".
Kommentaarid: 85 loe/lisa Kasutajad arvavad:  :: 0 :: 2 :: 78
tagasi üles
vaata kasutaja infot saada privaatsõnum
cannuman
HV vaatleja

liitunud: 05.06.2007




sõnum 05.08.2010 14:29:59 vasta tsitaadiga

Tänud mikk, nii oligi.
Kommentaarid: 3 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 3
tagasi üles
vaata kasutaja infot saada privaatsõnum
2korda2
HV kasutaja

liitunud: 19.07.2003




sõnum 05.08.2010 17:07:23 vasta tsitaadiga

Märkused:
1. Lõid aliase "b" aga seda ei kasuta. Kas MySQL oskab seda koodi käivitada ja saab aru, kust tabelist võtta veerud "date" ja "product_key"? Vaata ka siia.
2. Jällegi, pole MySQL'i kasutanud aga kas tõesti on vajalik iga tingimuse ümber omaette sulud panna?
3. Sisuline küsimus. Kas ma sain õigesti aru, et kõigile sama tootega seotud ridadele (välja arvatud kuupäeva järgi viimane), omistad täpselt ühesuguse "kehtiv kuni" väärtuse (kui see on määramata)? Ehk siis lõpptulemus võib välja näha selline (kuidas leitakse date_calc on juba teine teema):
Toode Kuupäev Kehtiv Kuni
1 01.01.2010 01.08.2010
1 01.02.2010 01.08.2010
1 01.03.2010 01.08.2010
1 30.06.2010 15.08.2010

See tulemus ongi see mida vaja? Või peaks igal ajahetkel ikkagi kehtima vaid 1 rida? Näiteks milline rida kehtib kuupäeval 15.06.2010?
Kommentaarid: 7 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
cannuman
HV vaatleja

liitunud: 05.06.2007




sõnum 16.08.2010 15:15:06 vasta tsitaadiga

2korda2,

Ei sellist asja ei ole. Igal ajahetkel kehtib täpselt 1 rida. Ühe rea kehtivuse lõpp on järgmise alguseks. See asi toimib nüüd ilusasti (võimalik et seetõttu, et korraga saab olla vaid üks puuduv väärtus iga toote kohta tunnusel "kehtiv_kuni". Ja kasutan MS SQl mitte MySql tegelikult.

Uues mure on järgmine. Nimelt on tarvis hinna kehtivuse lõpp muuta, kui kogus nulli jookseb...Ehk siis teisest tabelist saan ajahetke (change_date) kui kogus on 0 ja otsin vtp_price tabelist rida, kuhu see ajahet vahele jääb. Vastaval real tahan muuta date_end veeru väärtust, asendades selle hetkega kui kogus nulliks muutus.

Kahjuks ei oska kusagilt oma sql lause kohta veateadet ka otsida. Task muutub lihtsalt punaseks ja viga pean ise taga otsima. Kasutan SSIS tarkvara. Kogemust ja teadmisi vähe, ehk keegi oskab öelda kus viga on, või kas selline lähenemine üldse on õige sellise lähteülesane puhul...

sql:
  1. UPDATE vtp_price
  2. SET  date_end =
  3.  
  4.                      SELECT    change_date
  5.                             FROM         vtp_quantity2 AS b
  6.                             WHERE      b.quantity = 0 AND a.product_key = b.product_key
  7.  
  8.  
  9. FROM         vtp_price AS a
  10. WHERE     b.change_date BETWEEN a.date_calc AND a.date_end AND b.quantity = 0


Ilmselt on asi selles, et kogus saab muutuda nulliks mitu korda. Ehk päring väljastab mulle rohkem kui ühe väärtuse, mida ühte lahtrisse asendada soovin...Muid vigu võib veel lisaks olla.
Kommentaarid: 3 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 3
tagasi üles
vaata kasutaja infot saada privaatsõnum
2korda2
HV kasutaja

liitunud: 19.07.2003




sõnum 16.08.2010 17:06:34 vasta tsitaadiga

cannuman,
päris sõbralik soovitus - võta ette mõni raamat stiilis "SQL for dummies". Sul on lihtsad süntaktilised vead (viimases näites - kuhu käivad sulud ja kuhu tingimused?).
Seejärel vaata üle oma andmemudel (kordan küsimust kasutatava UML vahendi kohta ja soovitust Enterprise Architect osas). Nagu vastusest minu viimasele küsimusele välja tuleb, teed sa loogikavigu - loota, et alati on ainult 1 rida, mis mingile tingimusele vastab (ja see tingimus ei ole PK) on paremal juhul lihtsameelne. Loogikavead tulevad tihtipeale just sellest, et puudub ülevaade andmemudelist.
Kui see selge, siis hakka SQL käivitamiseks kasutama vahendit, mis selleks mõeldud on (PLSQL developer?). Nii saad ka korrektseid veateateid.
Kommentaarid: 7 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
wiinanina
HV kasutaja

liitunud: 27.02.2003




sõnum 17.08.2010 11:12:46 vasta tsitaadiga

cannuman kirjutas:
...

Kahjuks ei oska kusagilt oma sql lause kohta veateadet ka otsida. Task muutub lihtsalt punaseks ja viga pean ise taga otsima. Kasutan SSIS tarkvara. Kogemust ja teadmisi vähe, ehk keegi oskab öelda kus viga on, või kas selline lähenemine üldse on õige sellise lähteülesane puhul...

sql:
  1. UPDATE vtp_price
  2. SET  date_end =
  3.  
  4.                      SELECT    change_date
  5.                             FROM         vtp_quantity2 AS b
  6.                             WHERE      b.quantity = 0 AND a.product_key = b.product_key
  7.  
  8.  
  9. FROM         vtp_price AS a
  10. WHERE     b.change_date BETWEEN a.date_calc AND a.date_end AND b.quantity = 0


Ilmselt on asi selles, et kogus saab muutuda nulliks mitu korda. Ehk päring väljastab mulle rohkem kui ühe väärtuse, mida ühte lahtrisse asendada soovin...Muid vigu võib veel lisaks olla.





Kui MSSQL siis

1. alamselectil oleks sulge vaja
2. tabelit b ei saa niimoodi kasutada. a järel olev where ei saa seda b.change_date kätte.
3. between pole hea, kuna siis hakatakse pidevalt samadele kirjetele updatesid tegema


Kui oled kindel, et kattuvaid perioode pole siis võid proovida midagi sellist

update a
set date_end = b.change_date

from vtp_price AS a
inner join vtp_quantity2 AS b on (a.product_key = b.product_key AND b.quantity = 0 and b.change_date >= a.date_calc AND b.change_date < a.date_end )


Miks sa b tabelile trigerit ei kirjuta mis a tabelit muudaks??
Kommentaarid: 1 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 1
tagasi üles
vaata kasutaja infot saada privaatsõnum
2korda2
HV kasutaja

liitunud: 19.07.2003




sõnum 06.09.2010 16:42:37 vasta tsitaadiga

wiinanina kirjutas:
3. between pole hea, kuna siis hakatakse pidevalt samadele kirjetele updatesid tegema

Ma ei tea, mida sellega siin mõtlesid aga tsüklilist update-i siin ei teki. Kõiki tingimustele vastavaid kirjeid uuendatakse 1 kord. Kui küsimus on selles, et X ajaühiku pärast on vaja lauset uuesti käivitada ja et siis mõttetult liigseid ridu üle ei käidaks, siis pigem tuleks appi võtta lisatingimus(ed). Kas date_end enne update-i on väärtustatud? Kui mitte siis lisaks tingimuseks "... and date_end is null". Variant 2: koos update-ga hakata täitma ka lisaveergu, kuhu panna lipp tähendusega "rida on juba korrastatud". Täiendada update tingimusi nii, et uuendatakse ainult kirjeid, millel lipp puudu.
Kommentaarid: 7 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
näita postitusi alates eelmisest:   
uus teema   vasta Tarkvara »  Programmeerimine »  SQL abi mine lehele eelmine  1, 2
[vaata eelmist teemat] [vaata järgmist teemat]
 lisa lemmikuks
näita foorumit:  
 ignoreeri teemat 
sa ei või postitada uusi teemasid siia foorumisse
sa ei või vastata selle foorumi teemadele
sa ei või muuta oma postitusi selles foorumis
sa ei või kustutada oma postitusi selles foorumis
sa ei või vastata küsitlustele selles foorumis
sa ei saa lisada manuseid selles foorumis
sa võid manuseid alla laadida selles foorumis



Hinnavaatlus ei vastuta foorumis tehtud postituste eest.