SQL pomoč

Jumpy17

Zelenc'
12. sep 2011
5
0
1
Hoj!
Nikakmor mi ne rata sestaviti ukaza za sledeči primer.

Imamo dve tabeli - Tabela1 in Tabela2. Vsaka tabela predstavlja svoj mesec, v njej pa so recimo vpisani mobilni uporabniki. Imamo stolpce Številka, čas, klic in SMS. Kako v Tabeli2 vidim nove zapise(številke), ki so na novo uporabile storitev SMS?
V Tabeli2 se načeloma nahajajo vse številke iz Tabele1 in nekaj dodatnih, ki so poslale SMS.

EXCEPT ne pride v poštev, ker primerja celotni tabeli in izpiše razliko celotne tabele.

Hvala za pomoč
smile-1.gif
 

doto

Fizikalc
25. jul 2007
3.175
0
36
Select * from tabela2 where stevilka not in ( select distinct stevilka from tabela1 )
 

Jurij

Pripravnik
22. sep 2007
821
0
16
Distinct lahko izpustiš, drugače pa je to to. Pa ne pozabi indeksa nad tabela1.stevilka.
 

futuristic

geđet frik
Osebje foruma
13. jul 2007
7.920
662
113
Zgornja rešitev bo res delovala, ampak je performančno najslabša možna.

Prav bi bilo takole:
sql1.png

Rešitev:
sql2.png
 

Jurij

Pripravnik
22. sep 2007
821
0
16
Sem šel tudi jaz preverjat, sem naredil 3 možne rešitve:

create table tel1 (stevilka varchar2(10), tel varchar2(1), sms varchar2(1), mesec number(2));
create table tel2 (stevilka varchar2(10), tel varchar2(1), sms varchar2(1), mesec number(2));
create index tel1_st on tel1(stevilka);

select *
from tel2 t2
where t2.stevilka not in (select t1.stevilka from tel1 t1)

select *
from tel2 t2
where not exists (select 1 from tel1 t1 where t1.stevilka = t2.stevilka)

select t2.*
from tel2 t2
, tel1 t1
where t1.stevilka(+) = t2.stevilka
and t1.stevilka is null

Prva je dejansko najslabša, mi naredi full table scan čez obe tabeli:
sql1.jpg


Drugi in tretji select sta ekvivalentna:
sql2-3.jpg


Seveda je odvisno tudi od baze, jaz sem primer naredil na Oracle 11R2, kakšen Microsoft se lahko obnaša drugače...
 

Jumpy17

Zelenc'
12. sep 2011
5
0
1
U, super.
Joinov mi pa ne uspe logicno nastudirati, da bi jih bolj pogosto uporabljal, tko da bi se verjetno posluzil kar prve resitve.
 

shootek

Fizikalc
3. sep 2007
916
102
43
select 1 from dual;
In kje je problem z joini (ok res je razlika kako napišeš v različnih izvedbah SQLa), vendar je tu dokaj simple logika.

Pogledaš kaj v prvi in drugi tabeli želiš povezati (oz. katera kolona med obema tabelama ustvarja povezavo). Pri tebi je to številka, ki je unikatna za enega uporabnika.

Če ti podam na enem lažjem primeru:

Tabela1 (A):
SIFRA_OSEBE
IME
PRIIMEK

Tabela2 (B):
SIFRA_OSEBE
ULICA
KRAJ

Kako bi sedaj dobil Ime, priimek, ulico in kraj osebe s šifro '666'?

SELECT A.IME,A.PRIIMEK,B.ULICA,B.KRAJ FROM A,B WHERE A.SIFRA_OSEBE = B.SIFRA_OSEBE AND A.SIFRA_OSEBE = '666'

Me pa še ena stvar muči (poklicna deformacija), vendar je verjetno napaka v razumevanju opisa problema. V prvem postu si želel dobiti vse, ki so na novo uporabili storitev SMS. Tega ti nobena od predlaganih rešitev ne poda (poda ti le ali je oseba opravila neko storitev v mesecu2 v mesecu1 pa ne, se pravi ali klic ali SMS), kar pomeni, da moraš dodati še en pogoj.

Probaj sam, drugače ti bomo priskočili na pomoč.

 

futuristic

geđet frik
Osebje foruma
13. jul 2007
7.920
662
113
Citat:
Uporabnik shootek pravi:
SELECT A.IME,A.PRIIMEK,B.ULICA,B.KRAJ FROM A,B WHERE A.SIFRA_OSEBE = B.SIFRA_OSEBE AND A.SIFRA_OSEBE = '666'
Si v Oracle-u doma al zakaj take hecne joine pišeš?
grin1.gif
 

Jumpy17

Zelenc'
12. sep 2011
5
0
1
Shootek: najprej hvala za razlago - it seems so obvious now
smile-1.gif

Ja, morda sem res nekoliko nerodno napisal vprasanje. Zanima me le, katere so tiste nove stevilke, ki so se pojavile v tabeli2. Se pravi tiste ki se pojavljajo v obeh tabelah me ne zanimajo. Ce predvidevava da vsaka stevilka uporablja storitev SMS, lahko receva da vsak nov zapis predstavlja novo stevilko/uporabnika.
 

shootek

Fizikalc
3. sep 2007
916
102
43
select 1 from dual;
Join-i so najbolj osnovna stvar v SQL-u, vsaj ko hočeš vsaj kaj polresnega naredit, ker težko najdeš bazo, kjer so vsi podatki v eni tabeli (čeprav nekateri že pretiravajo z neko 8.normalno obliko
bonk.gif
). Je pa vsaj v Oraclu SQL stavek zelo pregledno sestavljen (dokler ne prideš do kake 400 vrstic):

SELECT (poveš kaj želiš in iz katere tabele se pravi npr A.IME)
FROM (iz katerih tabel želiš pridobiti podatke npr. ZAPOSLENI A (uporabljen je alias A zaradi tega da je pisanje hitrejše; lahko bi zgoraj napisal tudi ZAPOSLENI.IME)
WHERE (pod katerimi pogoji želiš imeti izpisane podatke, tu pridejo na vrsto povezave med tabelami (joini) A.IME = B.IME, outer-joini A.IME (+) = B:IME, kot tudi vsi ostali pogoji A.IME LIKE 'JUR%'
ORDER BY, GROUP BY (se pravi sortirano po, grupirano po,...)

To je čisto osnovna Oracle sintaksa, medtem ko ima M$ malo bolj po Karađiæevo (piši što govoriš).

To je vaja 1.1, naprej pa pridejo kompleksnejše stvari.
LP
 

Utisevalec

Guru
12. nov 2007
16.161
4.147
113
Citat:
Uporabnik shootek pravi:
Join-i so najbolj osnovna stvar v SQL-u, vsaj ko hočeš vsaj kaj polresnega naredit, ker težko najdeš bazo, kjer so vsi podatki v eni tabeli (čeprav nekateri že pretiravajo z neko 8.normalno obliko
bonk.gif
). Je pa vsaj v Oraclu SQL stavek zelo pregledno sestavljen (dokler ne prideš do kake 400 vrstic):

SELECT (poveš kaj želiš in iz katere tabele se pravi npr A.IME)
FROM (iz katerih tabel želiš pridobiti podatke npr. ZAPOSLENI A (uporabljen je alias A zaradi tega da je pisanje hitrejše; lahko bi zgoraj napisal tudi ZAPOSLENI.IME)
WHERE (pod katerimi pogoji želiš imeti izpisane podatke, tu pridejo na vrsto povezave med tabelami (joini) A.IME = B.IME, outer-joini A.IME (+) = B:IME, kot tudi vsi ostali pogoji A.IME LIKE 'JUR%'
ORDER BY, GROUP BY (se pravi sortirano po, grupirano po,...)

To je čisto osnovna Oracle sintaksa, medtem ko ima M$ malo bolj po Karađiæevo (piši što govoriš).

To je vaja 1.1, naprej pa pridejo kompleksnejše stvari.
LP

Napisano ni neka OracleTM sintaksa ampak splošna "SELECT" sintaksa vseh SQL (relacijskih) baz ker je BTW SQL postavljen v okvir ANSI standardov. Torej zgoraj napisano velja za vse SQL baze, razlike so mogoče v kakšnih podrobnostih kot so narekovaji, oklepaji itd..
 

stein

Fizikalc
16. sep 2007
19.575
1
36
Oracle podpira LEFT/RIGHT/INNER/OUTER JOIN-e.

Pa večina drugih tudi.
In ta sintaksa se priporoča.
 

Jurij

Pripravnik
22. sep 2007
821
0
16
Citat:
Uporabnik futuristic pravi:
Citat:
Uporabnik shootek pravi:
SELECT A.IME,A.PRIIMEK,B.ULICA,B.KRAJ FROM A,B WHERE A.SIFRA_OSEBE = B.SIFRA_OSEBE AND A.SIFRA_OSEBE = '666'
Si v Oracle-u doma al zakaj take hecne joine pišeš?
grin1.gif
To niso hecni joini, to so edini joini
smile-1.gif

Ne vem kako se je MS popravil, ampak včasih je bil to šrot napram Oraclu, v službi imam opravka z večjimi bazami kjer na MS itak nihče niti pomisli ne.
 
Nazadnje urejeno: