Avaleht
uus teema   vasta Tarkvara »  Programmeerimine »  SQL abi märgi kõik teemad loetuks
märgi mitteloetuks
vaata eelmist teemat :: vaata järgmist teemat
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:  
iFlop
Kreisi kasutaja
iFlop

liitunud: 03.05.2003



Autoriseeritud ID-kaardiga
sõnum 14.01.2009 15:13:11 SQL abi vasta tsitaadiga

Oleks SQLga natuke abi vaja. Täpsemalt on kasutusel MSi SQL server 2008 aga väga suur sisulist vahet ei tohiks selles olla. Esimesena on mul siin näidistabel, millest tahaks all pool olevat päringutulemust saada. Ise pakun, et lahenduseks on sub-query'd, mida ei oska hetkel õieti kasutada. Igatahes igasugused soovitused on teretulnud.

date        item    qty  color
29.12.2000  pear    4    yellow
30.12.2000  apple   7    green
1.01.2001   pear    2    green
1.01.2001   pear    2    yellow
3.01.2001   apple   5    yellow
4.01.2001   apple   3    yellow
4.01.2001   pear    4    yellow
4.01.2001   pear    8    green
6.01.2001   pear    6    green
6.01.2001   apple   8    green
7.01.2001   apple   5    yellow
8.01.2001   apple   4    green
12.01.2001  apple   3    yellow

Month   | Total | Green apples | % of Green apples
--------+-------+--------------+------------------
2000-12 | 11    | 7            | 63,64%
2001-01 | 50    | 12           | 24,00%
Kommentaarid: 67 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 66
tagasi üles
vaata kasutaja infot saada privaatsõnum
connor
HV kasutaja

liitunud: 19.02.2003




sõnum 14.01.2009 15:57:13 vasta tsitaadiga

Lahenduseks on jah sub-queryd ehk kokku tuleks teha 2 alampäringut mis kolmanda päringu left join'iga kokku panna.

Kas tegemist on kooliülesandega?
Kommentaarid: 31 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 28
tagasi üles
vaata kasutaja infot saada privaatsõnum
inzinz
HV kasutaja

liitunud: 26.01.2005




sõnum 14.01.2009 16:29:23 vasta tsitaadiga

Saab ilusti ka ühe päringuga tehtud:
SELECT substr(date,1,7) `Month`,sum(qty) `Total`,sum(if(color='green' and item='apple',qty,0))`Green apples`,concat(100*sum(if(color='green' and item='apple',qty,0))/sum(cnt),'%') `% of Green apples` from minutabel group by Month;


Antud näide on testitud Mysql andmebaasi peal, MSSQL koha pealt pole kindel kas substring(date,1,7) annab kuupäeva õiges formaadis ning kas '% of Green apples' tagastatakse kahe või enama komakohaga, soovitan testida icon_wink.gif
Päringu põhimõte on olemas, kui väljastamise vormingus midagi teisiti kui peaks, siis otsi manualist icon_wink.gif

_________________
Upload.ee - eestimaine failiupload
Kommentaarid: 4 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 4
tagasi üles
vaata kasutaja infot saada privaatsõnum
iFlop
Kreisi kasutaja
iFlop

liitunud: 03.05.2003



Autoriseeritud ID-kaardiga
sõnum 15.01.2009 12:51:31 vasta tsitaadiga

connor, tegu pole kahjuks kooliülesandega icon_razz.gif

Praegu avastasin, et olemas on ka selline asi nagu OVER Clause, millest võiks vist ka abi olla..

IF/CASE'ga mässamine tunduks nagu mingi häkk.. Või ma eksin? Lisaks tundub MSSQL CASE palju vastikum olevat kui MySQL IF()
Mis kuupäeva teisendusse puutub, siis sellega mul probleeme pole. Samas on jällegi MSSQL IMO palju jubedam: DATE_FORMAT(now(), '%Y-%m') vs CONVERT(VARCHAR(7), CURRENT_TIMESTAMP, 120)

Igasugused soovitused endiselt teretulnud.
Kommentaarid: 67 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 66
tagasi üles
vaata kasutaja infot saada privaatsõnum
wiinanina
HV kasutaja

liitunud: 27.02.2003




sõnum 15.01.2009 13:06:35 vasta tsitaadiga

ilma ülekontrollimata kirjutades peaks mssql-s hakkama pihta kuidagi niimoodi
select convert(char(7), date, 120) as Month , sum(qty) as Total , sum( case when item = 'apple' and color = 'green' then qty else 0 end ) as 'Green Apples' ...
Kommentaarid: 1 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 1
tagasi üles
vaata kasutaja infot saada privaatsõnum
iFlop
Kreisi kasutaja
iFlop

liitunud: 03.05.2003



Autoriseeritud ID-kaardiga
sõnum 10.09.2009 12:30:20 vasta tsitaadiga

Eelmine küsimus sai vastuse:
Spoiler Spoiler Spoiler
Nüüd aga uus, et kuidas join'da nii, et ridu juurde ei tuleks?
Põhimõtteliselt tahaks 2 tabelit niiviisi kokku panna:
tabel1
--------
A     
B     
C     

tabel2
---+---
A  | x
B  | y
B  | z

join 
--+---
A | x
B | y
C |   


Üks variant oleks, et tabel2 sisaldaks ka esimese tulba kohta järjestust, et joinimisel saaks seda kasutada:
tabel2   
--+---+---
A | 1 | x
B | 1 | y
B | 2 | z

Aga hetkel ei leia selleks ühtegi sobivat funtsiooni..
Kommentaarid: 67 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 66
tagasi üles
vaata kasutaja infot saada privaatsõnum
hexmex
HV kasutaja

liitunud: 13.06.2006




sõnum 10.09.2009 12:41:11 vasta tsitaadiga

iFlop kirjutas:

Nüüd aga uus, et kuidas join'da nii, et ridu juurde ei tuleks?


http://en.wikipedia.org/wiki/Join_(SQL)

_________________
Olgem sõbralikud!
Kommentaarid: 5 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 2
tagasi üles
vaata kasutaja infot saada privaatsõnum
iFlop
Kreisi kasutaja
iFlop

liitunud: 03.05.2003



Autoriseeritud ID-kaardiga
sõnum 11.09.2009 14:30:16 vasta tsitaadiga

hexmex,
Küsimus pole otseselt ju joinimises vaid järjestuse numbrite tegemises. Sest kui järjesuse number olemas, mis siis viga joini teha.
Igatahes peaks vastav funktsioon Oracle baasis töötama. Samas oleks ehk ka abi MySQLi jt. analoogsetest funktsioonidest.

Edit: selgituseks toon täpsemalt välja mida ma soovin. Lisaks nimele oleks vaja juurde tekitada järjestuse number nii, et iga erineva väärtuse kohta oleks oma järjestus:
name    | seq   name
--------+-------------
pirn    | 1     pirn
pirn    | 2     pirn
ploom   | 1     ploom
õun     | 1     õun
õun     | 2     õun
õun     | 3     õun
Kommentaarid: 67 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 66
tagasi üles
vaata kasutaja infot saada privaatsõnum
scrag
HV kasutaja

liitunud: 08.12.2003




sõnum 11.09.2009 15:56:57 vasta tsitaadiga

Midagi taolist äkki:

SELECT puuvili, ROW_NUMBER () OVER (PARTITION BY puuvili ORDER BY puuvili) AS seq
  FROM (SELECT 'pirn' AS puuvili
          FROM DUAL
        UNION ALL
        SELECT 'ploom' AS puuvili
          FROM DUAL
        UNION ALL
        SELECT 'õun' AS puuvili
          FROM DUAL
        UNION ALL
        SELECT 'õun' AS puuvili
          FROM DUAL
        UNION ALL
        SELECT 'pirn' AS puuvili
          FROM DUAL
        UNION ALL
        SELECT 'õun' AS puuvili
          FROM DUAL)


ROW_NUMBER funktsioon paistab sobivat.
Kommentaarid: 9 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 9
tagasi üles
vaata kasutaja infot saada privaatsõnum
Fukiku
Kreisi kasutaja
Fukiku

liitunud: 06.11.2003



Autoriseeritud ID-kaardiga
sõnum 11.09.2009 17:24:18 vasta tsitaadiga

scrag kirjutas:
Midagi taolist äkki:

SELECT puuvili, ROW_NUMBER () OVER (PARTITION BY puuvili ORDER BY puuvili) AS seq
  FROM (SELECT 'pirn' AS puuvili
          FROM DUAL
        UNION ALL
        SELECT 'ploom' AS puuvili
          FROM DUAL
        UNION ALL
        SELECT 'õun' AS puuvili
          FROM DUAL
        UNION ALL
        SELECT 'õun' AS puuvili
          FROM DUAL
        UNION ALL
        SELECT 'pirn' AS puuvili
          FROM DUAL
        UNION ALL
        SELECT 'õun' AS puuvili
          FROM DUAL)


ROW_NUMBER funktsioon paistab sobivat.

Lööge mind nüüd kõvasti, selle eest, et ma eksin, aga kas DUAL tabel ei ole Oracle spetsiifika ja teemaalgataja mainis just kui MS SQL'i kasutamist.. ?

_________________
Foxic is just a simple fox
Enne kui sa küsid oma küsimuse - küsi seda vannipardilt! Rangelt soovitatav enne programmeerimise alafoorumisse uue teema tegemist.
Kommentaarid: 2 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 2
tagasi üles
vaata kasutaja infot saada privaatsõnum
scrag
HV kasutaja

liitunud: 08.12.2003




sõnum 11.09.2009 17:49:50 vasta tsitaadiga

iFlop kirjutas:
... Igatahes peaks vastav funktsioon Oracle baasis töötama. ...

Ma saan aru, et vahepeal nagu ülesanne muutus ja nüüd peaks Oracle baasis asi töötama.
Kommentaarid: 9 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 9
tagasi üles
vaata kasutaja infot saada privaatsõnum
wiinanina
HV kasutaja

liitunud: 27.02.2003




sõnum 11.09.2009 21:30:47 vasta tsitaadiga

iFlop kirjutas:
Nüüd aga uus, et kuidas join'da nii, et ridu juurde ei tuleks?
Põhimõtteliselt tahaks 2 tabelit niiviisi kokku panna:
tabel1
--------
A     
B     
C     

tabel2
---+---
A  | x
B  | y
B  | z

join 
--+---
A | x
B | y
C |   


Üks variant oleks, et tabel2 sisaldaks ka esimese tulba kohta järjestust, et joinimisel saaks seda kasutada:
tabel2   
--+---+---
A | 1 | x
B | 1 | y
B | 2 | z

Aga hetkel ei leia selleks ühtegi sobivat funtsiooni..


jälle kool pihta hakanud icon_lol.gif

Kui mingi unikaalne väli tabelist puudu siis kindlalt kooliülesanne.

mssql võib näiteks niimoodi (lambist ja proovimata)

select distinct t1.field1, t2.field2 from tabel1 t1
left outer join tabel2 t2 on t1.field1= t2.field1
where not exists
(select * from tabel2 t3 where t2.field1 = t3.field1 and t3.field2 > t2.field2 )


või nii

select t1.field1,
(select top 1 t2.field2 from tabel2 t2 where t1.field1= t2.field1) field2
from tabel1 t1


või...
ei viitsi rohkem


edit: typod
Kommentaarid: 1 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 1
tagasi üles
vaata kasutaja infot saada privaatsõnum
iFlop
Kreisi kasutaja
iFlop

liitunud: 03.05.2003



Autoriseeritud ID-kaardiga
sõnum 12.09.2009 16:33:59 vasta tsitaadiga

scrag kirjutas:

ROW_NUMBER funktsioon paistab sobivat.

Jah, see peaks tõesti toimima.

wiinanina kirjutas:

jälle kool pihta hakanud icon_lol.gif

Kui mingi unikaalne väli tabelist puudu siis kindlalt kooliülesanne.

Pean kurvastama, aga tegu pole kooliülesandega icon_lol.gif
Tegu on hoopis ühe BI softiga kus ma ei saa isegi otse SQLi kirjutada.. Aga õnneks on seal siiski olemas running-count funktsioon, mis tegelikult teeb count (something) over (partition by ...)
Kommentaarid: 67 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 66
tagasi üles
vaata kasutaja infot saada privaatsõnum
cannuman
HV vaatleja

liitunud: 05.06.2007




sõnum 23.07.2010 16:23:47 vasta tsitaadiga

Tervitus. Ei hakka uue teemaga foorumit risustama, aga mure järgmine....

Andmetabel on järgmisel kujul:

date Nimi Value
18.05.10 12:17 Aadu 345
18.05.10 12:17 Vasja 54
18.05.10 12:17 Mari 75
18.05.10 12:17 Jurka 775
18.05.10 12:17 Dima 124
18.05.10 12:17 Tom 4587
04.06.10 0:05 Aadu 54872
09.06.10 0:05 Aadu 245
09.06.10 0:05 Vasja 77
09.06.10 0:05 Urmas 785
09.06.10 0:05 Ene 545

Ehk siis on nimi ja väärtus, mis on mingil kindlal ajahetkel arvutatud. Kuna väärtus muutub ajas (näiteks Aadul on 3x muutunud), siis oleks vaja lisada veerg, mis näitab kirje kehetivuse lõppu. Lõpu ajaks on uue kirje tekkimise aeg, mis käib sama inimese kohta...Ehk siis tulem peaks olema selline:

date Nimi Value Kehtivuse lõpp
18.05.10 12:17 Aadu 345 04.06.10 0:05
18.05.10 12:17 Vasja 54 09.06.10 0:05
18.05.10 12:17 Mari 75 NULL
18.05.10 12:17 Jurka 775 NULL
18.05.10 12:17 Dima 124 NULL
18.05.10 12:17 Tom 4587 NULL
04.06.10 0:05 Aadu 54872 09.06.10 0:05
09.06.10 0:05 Aadu 245 NULL
09.06.10 0:05 Vasja 77 NULL
09.06.10 0:05 Urmas 785 NULL
09.06.10 0:05 Ene 545 NULL


Oskab keegi aidata kuidas ma saaksin selle veeru tabelisse juurde arvutada...Kasvõi mingid märksõnad või funktsioonid millest võiks abi olla.

Aitäh ette.
Kommentaarid: 3 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 3
tagasi üles
vaata kasutaja infot saada privaatsõnum
iFlop
Kreisi kasutaja
iFlop

liitunud: 03.05.2003



Autoriseeritud ID-kaardiga
sõnum 23.07.2010 22:52:43 vasta tsitaadiga

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.
Kommentaarid: 67 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 66
tagasi üles
vaata kasutaja infot saada privaatsõnum
Renka
HV Guru
Renka

liitunud: 01.04.2002



Autoriseeritud ID-kaardiga
sõnum 24.07.2010 01:03:38 vasta tsitaadiga

Kas min asemel ei peaks olema max?
_________________
There is no place like 127.0.0.1
Kommentaarid: 71 loe/lisa Kasutajad arvavad:  :: 2 :: 1 :: 61
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
iFlop
Kreisi kasutaja
iFlop

liitunud: 03.05.2003



Autoriseeritud ID-kaardiga
sõnum 24.07.2010 14:38:06 vasta tsitaadiga

Renka, loomulikult ikka max() icon_smile.gif
Kommentaarid: 67 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 66
tagasi üles
vaata kasutaja infot saada privaatsõnum
kiiver
HV vaatleja

liitunud: 03.04.2003




sõnum 24.07.2010 16:16:52 vasta tsitaadiga

iFlop, päringus olev test.date < kuupäev ei saa küll minu arvates õiget tulemust anda, min() on aga õige. Oracle päring oleks:
sql:
  1. SELECT a.aeg
  2.      , a.nimi
  3.      , a.value
  4.      , (SELECT min(b.aeg)
  5.         FROM test b
  6.         WHERE b.aeg > a.aeg
  7.           AND b.nimi = a.nimi) AS kehtivuse_lopp
  8. FROM test a
Kommentaarid: 3 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 3
tagasi üles
vaata kasutaja infot saada privaatsõnum
Renka
HV Guru
Renka

liitunud: 01.04.2002



Autoriseeritud ID-kaardiga
sõnum 24.07.2010 16:18:14 vasta tsitaadiga

kiiver, sul õigus muidugi. iFlop näide võttis ju eelneva rea aja lõpuks mitte järgneva thumbs_up.gif
_________________
There is no place like 127.0.0.1
Kommentaarid: 71 loe/lisa Kasutajad arvavad:  :: 2 :: 1 :: 61
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
cannuman
HV vaatleja

liitunud: 05.06.2007




sõnum 27.07.2010 13:13:33 vasta tsitaadiga

Tänud asi korras, suurepärane icon_wink.gif

Tekkis aga uus küsimus...

Tabelis 4 veergu:

Kuu, Aasta, Toode, Tellija. Unikaalse võtme annavad 4 veergu kokku. Kuidas tekitada Primaarse võtme veerg (võti üheveeruline)?
Kommentaarid: 3 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 3
tagasi üles
vaata kasutaja infot saada privaatsõnum
kiiver
HV vaatleja

liitunud: 03.04.2003




sõnum 27.07.2010 14:37:54 vasta tsitaadiga

Ei saanud võibolla küsimusest täpselt aru aga primaarseks võtmeks tekitaksin uue veeru ID (sequence) ja nende olemasoleva 4 veeru peale paneks unikaalse indeksi.

EDIT: midagi sellist siis kui ID veergu pole vaja:
create table test (a number, b number, c number, d number, primary key (a, b, c, d))
Kommentaarid: 3 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 3
tagasi üles
vaata kasutaja infot saada privaatsõnum
2korda2
HV kasutaja

liitunud: 19.07.2003



Autoriseeritud ID-kaardiga
sõnum 27.07.2010 15:11:15 vasta tsitaadiga

kiiver kirjutas:
Ei saanud võibolla küsimusest täpselt aru aga primaarseks võtmeks tekitaksin uue veeru ID (sequence) ja nende olemasoleva 4 veeru peale paneks unikaalse indeksi.

EDIT: midagi sellist siis kui ID veergu pole vaja:
create table test (a number, b number, c number, d number, primary key (a, b, c, d))


PK üle mitme veeru on muidugi saatanast. Lisaveerg on ainuõige lahendus. Kui seda teha ei saa, siis üle mitme veeru tehakse (häda korral) UNIQUE indeks. Üldiselt paistab siit teemast järgemööda küsimusi, mida oleks saanud palju lihtsamalt lahendada, kui arhitekt oleks vahelduseks munemise lõpetanud ja ajusid kasutanud.
Kommentaarid: 7 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 7
tagasi üles
vaata kasutaja infot saada privaatsõnum
kiiver
HV vaatleja

liitunud: 03.04.2003




sõnum 27.07.2010 15:28:09 vasta tsitaadiga

2korda2 kirjutas:
kiiver kirjutas:
Ei saanud võibolla küsimusest täpselt aru aga primaarseks võtmeks tekitaksin uue veeru ID (sequence) ja nende olemasoleva 4 veeru peale paneks unikaalse indeksi.

EDIT: midagi sellist siis kui ID veergu pole vaja:
create table test (a number, b number, c number, d number, primary key (a, b, c, d))


PK üle mitme veeru on muidugi saatanast. Lisaveerg on ainuõige lahendus. Kui seda teha ei saa, siis üle mitme veeru tehakse (häda korral) UNIQUE indeks. Üldiselt paistab siit teemast järgemööda küsimusi, mida oleks saanud palju lihtsamalt lahendada, kui arhitekt oleks vahelduseks munemise lõpetanud ja ajusid kasutanud.

Tõsi, PK niimoodi üldjuhul ei tehta aga performance kadu võrreldes unique indexiga ei ole kuna PK ise on juba oma olemuselt UI. Vahe siis loetavuses ja kasutusmugavuses (ilma ID-ta on foreign key kasutamisega jama käes). Ise olen üle mitme veeru indekseid kasutanud päris palju ja ei tea nagu paremat lahendust nendes kohtades. Või mõtled selle all ka arhitektuuri probleemi?
Kommentaarid: 3 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 3
tagasi üles
vaata kasutaja infot saada privaatsõnum
cannuman
HV vaatleja

liitunud: 05.06.2007




sõnum 27.07.2010 15:43:27 vasta tsitaadiga

2korda2 kirjutas:
Üldiselt paistab siit teemast järgemööda küsimusi, mida oleks saanud palju lihtsamalt lahendada, kui arhitekt oleks vahelduseks munemise lõpetanud ja ajusid kasutanud.


arhitekt õpib alles, sellest ka küsimused icon_smile.gif

Lahendasin asja nii:

ALTER TABLE my_dim
ADD my_key INT IDENTITY(1,1) PRIMARY KEY
Kommentaarid: 3 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 3
tagasi üles
vaata kasutaja infot saada privaatsõnum
2korda2
HV kasutaja

liitunud: 19.07.2003



Autoriseeritud ID-kaardiga
sõnum 27.07.2010 16:09:03 vasta tsitaadiga

Ma pean tunnistama, et olen hakkama saanud sisuliselt ilma mitme veeru UI-deta. Vahel harva on mõni sisse lipsanud. ID veerg on see, mille järgi käib kogu FK viitamine. UI tuleb vahel mängu vaid mingi päringu optimeerimise tarvis (tabelites M+ kirjeid).
Ma tegin viimati ilma ID-ta tabeli kunagi eelmise aasta alguses, sest üks javanäpp arvas, et tal on sedasi seosetabelit (TABEL1_ID, TABEL2_ID) lihtsam täita. Pool aastat hiljem oli vaja teha suurem täiendus ja siis selgus, et oli ikka loll mõte ja sai ka sinna ID veerg. Pmst pole mõtet selle kallal palju mõtiskleda - nii on maailmas juba mitukümmend aastat tehtud ja ju siis on hea, kui kõik ikka nii teevad. Ruumi kokkuhoid vms põhjused on "so 60's".

PS. Cannuman,
selle veeru nimi on ID, igasugu my_personal_favorite_identification_key-nimelised veerunimed tekitavad ainult segadust. Nii saab aga pole ilus icon_razz.gif
Ah, kui ma juba alustasin - viisakas oleks ka, kui ID oleks alati tabelis ESIMENE veerg. See pole nii oluline aga viisakas siiski.
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 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



Autoriseeritud ID-kaardiga
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



Online
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



Autoriseeritud ID-kaardiga
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



Autoriseeritud ID-kaardiga
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



Autoriseeritud ID-kaardiga
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
[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.