Hinnavaatlus
:: Foorum
:: Uudised
:: Ärifoorumid
:: HV F1 ennustusvõistlus
:: Pangalink
:: Telekavad
:: HV toote otsing
|
|
autor |
|
iFlop
Kreisi kasutaja

liitunud: 03.05.2003
|
14.01.2009 15:13:11
SQL abi |
|
|
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 |
|
 |
connor
HV kasutaja
liitunud: 19.02.2003
|
14.01.2009 15:57:13
|
|
|
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 |
|
 |
inzinz
HV kasutaja
liitunud: 26.01.2005
|
14.01.2009 16:29:23
|
|
|
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
Päringu põhimõte on olemas, kui väljastamise vormingus midagi teisiti kui peaks, siis otsi manualist
_________________ Upload.ee - eestimaine failiupload |
|
Kommentaarid: 4 loe/lisa |
Kasutajad arvavad: |
   |
:: |
0 :: |
0 :: |
4 |
|
tagasi üles |
|
 |
iFlop
Kreisi kasutaja

liitunud: 03.05.2003
|
15.01.2009 12:51:31
|
|
|
connor, tegu pole kahjuks kooliülesandega
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 |
|
 |
wiinanina
HV kasutaja
liitunud: 27.02.2003
|
15.01.2009 13:06:35
|
|
|
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 |
|
 |
iFlop
Kreisi kasutaja

liitunud: 03.05.2003
|
10.09.2009 12:30:20
|
|
|
Eelmine küsimus sai vastuse:
Spoiler 
Hetkel sain subquery'ga selle näite põhjal soovitava tulemuse:
SELECT CONVERT(VARCHAR(7), date, 120) as Month, total, SUM(qty) as 'Green Apples', SUM(qty)/total AS '% of Green apples'
FROM (
SELECT CONVERT(VARCHAR(7), date, 120) as Month, SUM(qty) as total
FROM tabel
GROUP BY CONVERT(VARCHAR(7), date, 120)
)SUB join tabel on SUB.Month = CONVERT(VARCHAR(7), date, 120)
WHERE item = 'apple' AND color = 'Green'
GROUP BY CONVERT(VARCHAR(7), date, 120), total |
Kui kellelgi on soovitusi kuidas sama asja ilusamalt/efeltiivsemalt teha, siis andku teada.
Nüüd peab vaatama, kas saan selle näite põhjal ka päris DBst asjad õieti kätta..
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 |
|
 |
hexmex
HV kasutaja
liitunud: 13.06.2006
|
|
Kommentaarid: 5 loe/lisa |
Kasutajad arvavad: |
   |
:: |
0 :: |
1 :: |
2 |
|
tagasi üles |
|
 |
iFlop
Kreisi kasutaja

liitunud: 03.05.2003
|
11.09.2009 14:30:16
|
|
|
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 |
|
 |
scrag
HV kasutaja
liitunud: 08.12.2003
|
11.09.2009 15:56:57
|
|
|
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 |
|
 |
Fukiku
Kreisi kasutaja

liitunud: 06.11.2003
|
11.09.2009 17:24:18
|
|
|
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 |
|
 |
scrag
HV kasutaja
liitunud: 08.12.2003
|
11.09.2009 17:49:50
|
|
|
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 |
|
 |
wiinanina
HV kasutaja
liitunud: 27.02.2003
|
11.09.2009 21:30:47
|
|
|
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
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 |
|
 |
iFlop
Kreisi kasutaja

liitunud: 03.05.2003
|
12.09.2009 16:33:59
|
|
|
scrag kirjutas: |
ROW_NUMBER funktsioon paistab sobivat. |
Jah, see peaks tõesti toimima.
wiinanina kirjutas: |
jälle kool pihta hakanud
Kui mingi unikaalne väli tabelist puudu siis kindlalt kooliülesanne.
|
Pean kurvastama, aga tegu pole kooliülesandega
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 |
|
 |
cannuman
HV vaatleja
liitunud: 05.06.2007
|
23.07.2010 16:23:47
|
|
|
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 |
|
 |
iFlop
Kreisi kasutaja

liitunud: 03.05.2003
|
23.07.2010 22:52:43
|
|
|
cannuman, tundub, et lihtsa subquery'ga saab soovitud tulemuse. Testitud MySQL päring:
sql:
|
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' 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 |
|
 |
Renka
HV Guru

liitunud: 01.04.2002
|
24.07.2010 01:03:38
|
|
|
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 |
|
 |
iFlop
Kreisi kasutaja

liitunud: 03.05.2003
|
24.07.2010 14:38:06
|
|
|
Renka, loomulikult ikka max()
|
|
Kommentaarid: 67 loe/lisa |
Kasutajad arvavad: |
   |
:: |
0 :: |
0 :: |
66 |
|
tagasi üles |
|
 |
kiiver
HV vaatleja
liitunud: 03.04.2003
|
24.07.2010 16:16:52
|
|
|
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:
|
SELECT a.aeg , a.nimi , a.value , (SELECT min(b.aeg) FROM test b WHERE b.aeg > a.aeg AND b.nimi = a.nimi) AS kehtivuse_lopp FROM test a
|
|
|
Kommentaarid: 3 loe/lisa |
Kasutajad arvavad: |
   |
:: |
0 :: |
0 :: |
3 |
|
tagasi üles |
|
 |
Renka
HV Guru

liitunud: 01.04.2002
|
24.07.2010 16:18:14
|
|
|
kiiver, sul õigus muidugi. iFlop näide võttis ju eelneva rea aja lõpuks mitte järgneva
_________________ There is no place like 127.0.0.1 |
|
Kommentaarid: 71 loe/lisa |
Kasutajad arvavad: |
   |
:: |
2 :: |
1 :: |
61 |
|
tagasi üles |
|
 |
cannuman
HV vaatleja
liitunud: 05.06.2007
|
27.07.2010 13:13:33
|
|
|
Tänud asi korras, suurepärane
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 |
|
 |
kiiver
HV vaatleja
liitunud: 03.04.2003
|
27.07.2010 14:37:54
|
|
|
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 |
|
 |
2korda2
HV kasutaja
liitunud: 19.07.2003
|
27.07.2010 15:11:15
|
|
|
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 |
|
 |
kiiver
HV vaatleja
liitunud: 03.04.2003
|
27.07.2010 15:28:09
|
|
|
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 |
|
 |
cannuman
HV vaatleja
liitunud: 05.06.2007
|
27.07.2010 15:43:27
|
|
|
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
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 |
|
 |
2korda2
HV kasutaja
liitunud: 19.07.2003
|
27.07.2010 16:09:03
|
|
|
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
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 |
|
 |
|