/ Forside / Teknologi / Udvikling / SQL / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
SQL
#NavnPoint
pmbruun 1704
niller 962
fehaar 730
Interkril.. 701
ellebye 510
pawel 510
rpje 405
pete 350
gibson 320
10  smorch 260
mySql - mangler et hint til en SELECT WHER~
Fra : Gert Krabsen


Dato : 15-06-07 21:10

Jeg har en tabel, der (meget forenklet) ser sådan ud:

Navn Nummer
Peter 5
Jens 5
Peter 6
Peter 12
Anders 4
Jens 6

Hvis jeg gerne vil have alle navne, der har tallet 5, 6 eller 12, så
bliver det:

SELECT DISTINCT tbl.Navn FROM tbl
WHERE tbl.Nummer in(5,6,12)

Og resultatet vil være:

Peter
Jens

No problemos.


Men hvis jeg gerne vil have alle navne, der har _alle_ tre numre 5 ,6,
12 (I dette tilfælde er resultatet Peter

...hvordan gør jeg lettest det???

Nogen, der har en go' ide?



mvh

Krabsen


 
 
Ukendt (15-06-2007)
Kommentar
Fra : Ukendt


Dato : 15-06-07 21:38

"Gert Krabsen"

> Navn Nummer
> Peter 5
> Jens 5
> Peter 6
> Peter 12
> Anders 4
> Jens 6
>
> Hvis jeg gerne vil have alle navne, der har tallet 5, 6 eller 12, så
> bliver det:
>
> SELECT DISTINCT tbl.Navn FROM tbl
> WHERE tbl.Nummer in(5,6,12)
>
> Og resultatet vil være:
>
> Peter
> Jens
>
> No problemos.
>
>
> Men hvis jeg gerne vil have alle navne, der har _alle_ tre numre 5 ,6, 12
> (I dette tilfælde er resultatet Peter
>
> ..hvordan gør jeg lettest det???
>
> Nogen, der har en go' ide?
>
Fjerner Distinct:

SELECT tbl.Navn FROM tbl
WHERE tbl.Nummer in(5,6,12)

--
Med venlig hilsen

Tom Jensen
- Læs mere om asp og databaser her -
www.ffsoft.dk



Gert Krabsen (15-06-2007)
Kommentar
Fra : Gert Krabsen


Dato : 15-06-07 22:02

Tom Jensen wrote:
> "Gert Krabsen"
>
>
>>Navn Nummer
>>Peter 5
>>Jens 5
>>Peter 6
>>Peter 12
>>Anders 4
>>Jens 6
>>
>>Hvis jeg gerne vil have alle navne, der har tallet 5, 6 eller 12, så
>>bliver det:
>>
>> SELECT DISTINCT tbl.Navn FROM tbl
>> WHERE tbl.Nummer in(5,6,12)
>>
>>Og resultatet vil være:
>>
>>Peter
>>Jens
>>
>>No problemos.
>>
>>
>>Men hvis jeg gerne vil have alle navne, der har _alle_ tre numre 5 ,6, 12
>>(I dette tilfælde er resultatet Peter
>>
>>..hvordan gør jeg lettest det???
>>
>>Nogen, der har en go' ide?
>>
>
> Fjerner Distinct:
>
> SELECT tbl.Navn FROM tbl
> WHERE tbl.Nummer in(5,6,12)
>

Nixen - den har jeg desværre allerede prøvet. Den giver

Peter
Peter
Peter
Jens
Jens


og Jens skal jo ikke med, da han ikke har alle tre numre.. ;-(


Michael Zedeler (15-06-2007)
Kommentar
Fra : Michael Zedeler


Dato : 15-06-07 22:25

Gert Krabsen wrote:
> Jeg har en tabel, der (meget forenklet) ser sådan ud:
>
> Navn Nummer
> Peter 5
> Jens 5
> Peter 6
> Peter 12
> Anders 4
> Jens 6
>
> Hvis jeg gerne vil have alle navne, der har tallet 5, 6 eller 12, så
> bliver det:
>
> SELECT DISTINCT tbl.Navn FROM tbl
> WHERE tbl.Nummer in(5,6,12)
>
> Og resultatet vil være:
>
> Peter
> Jens
>
> No problemos.
>
> Men hvis jeg gerne vil have alle navne, der har _alle_ tre numre 5 ,6,
> 12 (I dette tilfælde er resultatet Peter
>
> ..hvordan gør jeg lettest det???
>
> Nogen, der har en go' ide?

SELECT COUNT(*), tbl.Navn FROM tbl
WHERE tbl.Nummer in(5,6,12)
GROUP BY tbl.Navn
HAVING COUNT(*) = 3

Mvh. Michael.

Gert Krabsen (15-06-2007)
Kommentar
Fra : Gert Krabsen


Dato : 15-06-07 22:46

Michael Zedeler wrote:
> Gert Krabsen wrote:
>
>> Jeg har en tabel, der (meget forenklet) ser sådan ud:
>>
>> Navn Nummer
>> Peter 5
>> Jens 5
>> Peter 6
>> Peter 12
>> Anders 4
>> Jens 6
>>
>> Hvis jeg gerne vil have alle navne, der har tallet 5, 6 eller 12, så
>> bliver det:
>>
>> SELECT DISTINCT tbl.Navn FROM tbl
>> WHERE tbl.Nummer in(5,6,12)
>>
>> Og resultatet vil være:
>>
>> Peter
>> Jens
>>
>> No problemos.
>>
>> Men hvis jeg gerne vil have alle navne, der har _alle_ tre numre 5 ,6,
>> 12 (I dette tilfælde er resultatet Peter
>>
>> ..hvordan gør jeg lettest det???
>>
>> Nogen, der har en go' ide?
>
>
> SELECT COUNT(*), tbl.Navn FROM tbl
> WHERE tbl.Nummer in(5,6,12)
> GROUP BY tbl.Navn
> HAVING COUNT(*) = 3

Ja, den har jeg osse tænkt på. Men jeg glemte i mit eksempel, at der
faktisk godt kan være mere end en linie med samme kombination af Navn +
nummer:

>> Navn Nummer
>> Peter 5
>> Jens 5
>> Peter 6
>> Peter 6
>> Peter 12
>> Anders 4
>> Jens 6

...fordi tabellen indeholder andre felter - men felter, der ikke kan
indgå i denne SQL.

Eks.
Navn Nummer Værdi
>> Peter 6 Brun
>> Peter 6 Gul
>> Peter 5 Brun
etc..

'Værdi' er ikke foruddefineret, så vi bare kan skille den ud i en ekstra
tabel..


Noget i denne retning ville være godt, hvis det ellers virkede:

SELECT Count (distinct(*)) AS Udtryk1, testtabel.navn
FROM testtabel
WHERE (((testtabel.nummer) In (5,6,12)))
GROUP BY testtabel.navn
HAVING (((Count(*))=3));


Og jeg har ikke kunnet kringle den krølle

Gert Krabsen (15-06-2007)
Kommentar
Fra : Gert Krabsen


Dato : 15-06-07 23:05

Gert Krabsen wrote:
> Michael Zedeler wrote:
>
>> Gert Krabsen wrote:
>>
>>> Jeg har en tabel, der (meget forenklet) ser sådan ud:
>>>
>>> Navn Nummer
>>> Peter 5
>>> Jens 5
>>> Peter 6
>>> Peter 12
>>> Anders 4
>>> Jens 6
>>>
>>> Hvis jeg gerne vil have alle navne, der har tallet 5, 6 eller 12, så
>>> bliver det:
>>>
>>> SELECT DISTINCT tbl.Navn FROM tbl
>>> WHERE tbl.Nummer in(5,6,12)
>>>
>>> Og resultatet vil være:
>>>
>>> Peter
>>> Jens
>>>
>>> No problemos.
>>>
>>> Men hvis jeg gerne vil have alle navne, der har _alle_ tre numre 5
>>> ,6, 12 (I dette tilfælde er resultatet Peter
>>>
>>> ..hvordan gør jeg lettest det???
>>>
>>> Nogen, der har en go' ide?
>>
>>
>>
>> SELECT COUNT(*), tbl.Navn FROM tbl
>> WHERE tbl.Nummer in(5,6,12)
>> GROUP BY tbl.Navn
>> HAVING COUNT(*) = 3
>
>
> Ja, den har jeg osse tænkt på. Men jeg glemte i mit eksempel, at der
> faktisk godt kan være mere end en linie med samme kombination af Navn +
> nummer:
>
> >> Navn Nummer
> >> Peter 5
> >> Jens 5
> >> Peter 6
> >> Peter 6
> >> Peter 12
> >> Anders 4
> >> Jens 6
>
> ..fordi tabellen indeholder andre felter - men felter, der ikke kan
> indgå i denne SQL.
>
> Eks.
> Navn Nummer Værdi
> >> Peter 6 Brun
> >> Peter 6 Gul
> >> Peter 5 Brun
> etc..
>
> 'Værdi' er ikke foruddefineret, så vi bare kan skille den ud i en ekstra
> tabel..
>


Denne ser ud til at virke:

---------
SELECT Count(*) AS Udtryk1, tbl.navn
FROM (

SELECT DISTINCTROW tbl.navn, tbl.nummer
FROM tbl
WHERE tbl.nummer In ( '5','6','12')
GROUP BY tbl.navn, tbl.nummer
)
GROUP BY tbl.navn
HAVING Count( *)=3;
---------


Jeg skal naturligvis have testet med flere kombinationsmuligheder, men
det ser lovende ud - tak for dit hint!



mvh
Krabsen



Michael Zedeler (15-06-2007)
Kommentar
Fra : Michael Zedeler


Dato : 15-06-07 23:02

Gert Krabsen wrote:
> Michael Zedeler wrote:
>>
>> SELECT COUNT(*), tbl.Navn FROM tbl
>> WHERE tbl.Nummer in(5,6,12)
>> GROUP BY tbl.Navn
>> HAVING COUNT(*) = 3
>
> Ja, den har jeg osse tænkt på. Men jeg glemte i mit eksempel, at der
> faktisk godt kan være mere end en linie med samme kombination af Navn +
> nummer:
>
> >> Navn Nummer
> >> Peter 5
> >> Jens 5
> >> Peter 6
> >> Peter 6
> >> Peter 12
> >> Anders 4
> >> Jens 6
>
> ..fordi tabellen indeholder andre felter - men felter, der ikke kan
> indgå i denne SQL.
>
> Eks.
> Navn Nummer Værdi
> >> Peter 6 Brun
> >> Peter 6 Gul
> >> Peter 5 Brun
> etc..
>
> Noget i denne retning ville være godt, hvis det ellers virkede:
>
> SELECT Count (distinct(*)) AS Udtryk1, testtabel.navn
> FROM testtabel
> WHERE (((testtabel.nummer) In (5,6,12)))
> GROUP BY testtabel.navn
> HAVING (((Count(*))=3));

Prøv lige at checke hvilke værdier, du får når du skriver COUNT(
DISTINCT * ). Hvis den giver de rigtige værdier, skal du jo bare skrive
det samme i HAVING-afdelingen og så skulle den ged være barberet.

Mvh. Michael.

Leif Neland (17-06-2007)
Kommentar
Fra : Leif Neland


Dato : 17-06-07 08:59

Gert Krabsen wrote:
> Jeg har en tabel, der (meget forenklet) ser sådan ud:
>
> Navn Nummer
> Peter 5
> Jens 5
> Peter 6
> Peter 12
> Anders 4
> Jens 6
>
> Men hvis jeg gerne vil have alle navne, der har _alle_ tre numre 5 ,6,
> 12 (I dette tilfælde er resultatet Peter
>
> ..hvordan gør jeg lettest det???

Man kunne også lave
select a.navn from tbl a
inner join tbl b using (navn)
inner join tbl c using(navn)
where a.nummer=5
and b.nummer=6
and c.nummer=12

Men om det er mere eller mindre effektivt end den anden metode, der er
givet, ved jeg ikke.

Den anden metode ser ihvertfald mere elegant ud...

Leif

>
> Nogen, der har en go' ide?
>
>
>
> mvh
>
> Krabsen



Michael Zedeler (17-06-2007)
Kommentar
Fra : Michael Zedeler


Dato : 17-06-07 10:12

Leif Neland wrote:
> Gert Krabsen wrote:
>> Jeg har en tabel, der (meget forenklet) ser sådan ud:
>>
>> Navn Nummer
>> Peter 5
>> Jens 5
>> Peter 6
>> Peter 12
>> Anders 4
>> Jens 6
>>
>> Men hvis jeg gerne vil have alle navne, der har _alle_ tre numre 5 ,6,
>> 12 (I dette tilfælde er resultatet Peter
>>
>> ..hvordan gør jeg lettest det???
>
> Man kunne også lave
> select a.navn from tbl a
> inner join tbl b using (navn)
> inner join tbl c using(navn)
> where a.nummer=5
> and b.nummer=6
> and c.nummer=12
>
> Men om det er mere eller mindre effektivt end den anden metode, der er
> givet, ved jeg ikke.
>
> Den anden metode ser ihvertfald mere elegant ud...

Join-metoden ovenfor er meget dyr.

Mvh. Michael.

Gert Krabsen (17-06-2007)
Kommentar
Fra : Gert Krabsen


Dato : 17-06-07 18:59

Michael Zedeler wrote:
> Leif Neland wrote:
>
>> Gert Krabsen wrote:
>>
>>> Jeg har en tabel, der (meget forenklet) ser sådan ud:
>>>
>>> Navn Nummer
>>> Peter 5
>>> Jens 5
>>> Peter 6
>>> Peter 12
>>> Anders 4
>>> Jens 6
>>>
>>> Men hvis jeg gerne vil have alle navne, der har _alle_ tre numre 5 ,6,
>>> 12 (I dette tilfælde er resultatet Peter
>>>
>>> ..hvordan gør jeg lettest det???
>>
>>
>> Man kunne også lave
>> select a.navn from tbl a
>> inner join tbl b using (navn)
>> inner join tbl c using(navn)
>> where a.nummer=5
>> and b.nummer=6
>> and c.nummer=12
>>
>> Men om det er mere eller mindre effektivt end den anden metode, der er
>> givet, ved jeg ikke.
>>
>> Den anden metode ser ihvertfald mere elegant ud...
>
> Join-metoden ovenfor er meget dyr.

Især, da antallet ikke er givet 3, men i princippet uendeligt (i praksis
dog typisk 3-8)

Så er det næsten bedre med et sekventiel gennemløb og så en gang
spagetti til at holde styr på 'scoren' for det enkelte navn.




> Mvh. Michael.

Kristian Damm Jensen (18-06-2007)
Kommentar
Fra : Kristian Damm Jensen


Dato : 18-06-07 15:46

Gert Krabsen wrote:
> Michael Zedeler wrote:
>> Leif Neland wrote:
>>
>>> Gert Krabsen wrote:
>>>
>>>> Jeg har en tabel, der (meget forenklet) ser sådan ud:
>>>>
>>>> Navn Nummer
>>>> Peter 5
>>>> Jens 5
>>>> Peter 6
>>>> Peter 12
>>>> Anders 4
>>>> Jens 6
>>>>
>>>> Men hvis jeg gerne vil have alle navne, der har _alle_ tre numre 5
>>>> ,6, 12 (I dette tilfælde er resultatet Peter
>>>>
>>>> ..hvordan gør jeg lettest det???
>>>
>>>
>>> Man kunne også lave
>>> select a.navn from tbl a
>>> inner join tbl b using (navn)
>>> inner join tbl c using(navn)
>>> where a.nummer=5
>>> and b.nummer=6
>>> and c.nummer=12
>>>
>>> Men om det er mere eller mindre effektivt end den anden metode, der
>>> er givet, ved jeg ikke.
>>>
>>> Den anden metode ser ihvertfald mere elegant ud...
>>
>> Join-metoden ovenfor er meget dyr.
>
> Især, da antallet ikke er givet 3, men i princippet uendeligt (i
> praksis dog typisk 3-8)

Det ændrer stadig ikke ret meget, hvis der er index på navn. Men det betyder
at den anden løsning (med group by) har store fordele i forhold til sin
flexibilitet.


--
Venlig hilsen /Best regards
Kristian Damm Jensen



Gert Krabsen (18-06-2007)
Kommentar
Fra : Gert Krabsen


Dato : 18-06-07 16:28

Kristian Damm Jensen wrote:
> Gert Krabsen wrote:
>
>>Michael Zedeler wrote:
>>
>>>Leif Neland wrote:
>>>
>>>
>>>>Gert Krabsen wrote:
>>>>
>>>>
>>>>>Jeg har en tabel, der (meget forenklet) ser sådan ud:
>>>>>
>>>>>Navn Nummer
>>>>>Peter 5
>>>>>Jens 5
>>>>>Peter 6
>>>>>Peter 12
>>>>>Anders 4
>>>>>Jens 6
>>>>>
>>>>>Men hvis jeg gerne vil have alle navne, der har _alle_ tre numre 5
>>>>>,6, 12 (I dette tilfælde er resultatet Peter
>>>>>
>>>>>..hvordan gør jeg lettest det???
>>>>
>>>>
>>>>Man kunne også lave
>>>>select a.navn from tbl a
>>>> inner join tbl b using (navn)
>>>> inner join tbl c using(navn)
>>>>where a.nummer=5
>>>> and b.nummer=6
>>>> and c.nummer=12
>>>>
>>>>Men om det er mere eller mindre effektivt end den anden metode, der
>>>>er givet, ved jeg ikke.
>>>>
>>>>Den anden metode ser ihvertfald mere elegant ud...
>>>
>>>Join-metoden ovenfor er meget dyr.
>>
>>Især, da antallet ikke er givet 3, men i princippet uendeligt (i
>>praksis dog typisk 3-8)
>
>
> Det ændrer stadig ikke ret meget, hvis der er index på navn. Men det betyder
> at den anden løsning (med group by) har store fordele i forhold til sin
> flexibilitet.

Der er (naturligvis!) index på alle de fleter, der kan blive brug for at
slå op i.

Og fleksibiliteten er ikke så stort et problem, idet SQL'en opbygges
dynamisk ud fra brugerens indtastning. Så det var performance, jeg
var/er nervøs for.

Men da jeg endnu ikke har fundet den helt geniale metode kan det være,
at jeg skal prøve denne.

Tak for tippene..




Michael Zedeler (18-06-2007)
Kommentar
Fra : Michael Zedeler


Dato : 18-06-07 21:18

Gert Krabsen wrote:
> Kristian Damm Jensen wrote:
>> Gert Krabsen wrote:
>>
>>> Michael Zedeler wrote:
>>>
>>>> Leif Neland wrote:
>>>>
>>>>
>>>>> Gert Krabsen wrote:
>>>>>
>>>>>
>>>>>> Jeg har en tabel, der (meget forenklet) ser sådan ud:
>>>>>>
>>>>>> Navn Nummer
>>>>>> Peter 5
>>>>>> Jens 5
>>>>>> Peter 6
>>>>>> Peter 12
>>>>>> Anders 4
>>>>>> Jens 6
>>>>>>
>>>>>> Men hvis jeg gerne vil have alle navne, der har _alle_ tre numre 5
>>>>>> ,6, 12 (I dette tilfælde er resultatet Peter
>>>>>>
>>>>>> ..hvordan gør jeg lettest det???
>>>>>
>>>>>
>>>>> Man kunne også lave
>>>>> select a.navn from tbl a
>>>>> inner join tbl b using (navn)
>>>>> inner join tbl c using(navn)
>>>>> where a.nummer=5
>>>>> and b.nummer=6
>>>>> and c.nummer=12
>>>>>
>>>>> Men om det er mere eller mindre effektivt end den anden metode, der
>>>>> er givet, ved jeg ikke.
>>>>>
>>>>> Den anden metode ser ihvertfald mere elegant ud...
>>>>
>>>> Join-metoden ovenfor er meget dyr.
>>>
>>> Især, da antallet ikke er givet 3, men i princippet uendeligt (i
>>> praksis dog typisk 3-8)
>>
>>
>> Det ændrer stadig ikke ret meget, hvis der er index på navn. Men det
>> betyder at den anden løsning (med group by) har store fordele i
>> forhold til sin flexibilitet.
>
> Der er (naturligvis!) index på alle de fleter, der kan blive brug for at
> slå op i.
>
> Og fleksibiliteten er ikke så stort et problem, idet SQL'en opbygges
> dynamisk ud fra brugerens indtastning. Så det var performance, jeg
> var/er nervøs for.
>
> Men da jeg endnu ikke har fundet den helt geniale metode kan det være,
> at jeg skal prøve denne.

Hvad er gurnden til at group by-tingen ikke virker?

Mvh. Michael.

Gert Krabsen (18-06-2007)
Kommentar
Fra : Gert Krabsen


Dato : 18-06-07 22:16

Michael Zedeler wrote:
> Gert Krabsen wrote:
>
>> Kristian Damm Jensen wrote:
>>
>>> Gert Krabsen wrote:
>>>
>>>> Michael Zedeler wrote:
>>>>
>>>>> Leif Neland wrote:
>>>>>
>>>>>
>>>>>> Gert Krabsen wrote:
>>>>>>
>>>>>>
>>>>>>> Jeg har en tabel, der (meget forenklet) ser sådan ud:
>>>>>>>
>>>>>>> Navn Nummer
>>>>>>> Peter 5
>>>>>>> Jens 5
>>>>>>> Peter 6
>>>>>>> Peter 12
>>>>>>> Anders 4
>>>>>>> Jens 6
>>>>>>>
>>>>>>> Men hvis jeg gerne vil have alle navne, der har _alle_ tre numre 5
>>>>>>> ,6, 12 (I dette tilfælde er resultatet Peter
>>>>>>>
>>>>>>> ..hvordan gør jeg lettest det???
>>>>>>
>>
>> Men da jeg endnu ikke har fundet den helt geniale metode kan det være,
>> at jeg skal prøve denne.
>
> Hvad er grunden til at group by-tingen ikke virker?


Som jeg skrev for snart længe siden

Jeg glemte i mit 'simplificerede' eksempel, at der faktisk godt kan være
mere end en linie med samme kombination af Navn + nummer (fordi der er
andre felter i tabellen):

>> Navn Nummer
>> Peter 5
>> Jens 5
>> Peter 6
>> Jens 5
>> Peter 12
>> Anders 4
>> Jens 6

Og det betyder, at der godt kan være (i dette tilfælde) 3, men ikke de
tre unikke. I ovennævnte har Jens 5,5,6. Altså tre hit, men nr. 12 mangler.

Jeg har på grund af andre hasteopgaver ikke grundafprøvet alle tips, men
det ser mest ud til, at jeg ender med:


For hver person dannes et Array af alle numre. Dette array holdes op mod
kriterierne med True/False som resultat. Er resultatet True, gennemførs
det-der-skal-ske.


mvh
Krabsen




Peter Brodersen (18-06-2007)
Kommentar
Fra : Peter Brodersen


Dato : 18-06-07 23:19

On Mon, 18 Jun 2007 23:16:08 +0200, Gert Krabsen
<fjernkrabsen@fjernkrabsenfjern.dk> wrote:

>Jeg glemte i mit 'simplificerede' eksempel, at der faktisk godt kan være
>mere end en linie med samme kombination af Navn + nummer (fordi der er
>andre felter i tabellen):

Her kan COUNT(DISTINCT ...) være på sin plads.

--
- Peter Brodersen
Kendt fra Internet

Michael Zedeler (18-06-2007)
Kommentar
Fra : Michael Zedeler


Dato : 18-06-07 23:24

Gert Krabsen wrote:
> Michael Zedeler wrote:
>> Gert Krabsen wrote:
>>
>>> Kristian Damm Jensen wrote:
>>>
>>>> Gert Krabsen wrote:
>>>>
>>>>> Michael Zedeler wrote:
>>>>>
>>>>>> Leif Neland wrote:
>>>>>>
>>>>>>
>>>>>>> Gert Krabsen wrote:
>>>>>>>
>>>>>>>
>>>>>>>> Jeg har en tabel, der (meget forenklet) ser sådan ud:
>>>>>>>>
>>>>>>>> Navn Nummer
>>>>>>>> Peter 5
>>>>>>>> Jens 5
>>>>>>>> Peter 6
>>>>>>>> Peter 12
>>>>>>>> Anders 4
>>>>>>>> Jens 6
>>>>>>>>
>>>>>>>> Men hvis jeg gerne vil have alle navne, der har _alle_ tre numre 5
>>>>>>>> ,6, 12 (I dette tilfælde er resultatet Peter
>>>>>>>>
>>>>>>>> ..hvordan gør jeg lettest det???
>>>>>>>
>>>
>>> Men da jeg endnu ikke har fundet den helt geniale metode kan det
>>> være, at jeg skal prøve denne.
>>
>> Hvad er grunden til at group by-tingen ikke virker?
>
> Som jeg skrev for snart længe siden
>
> Jeg glemte i mit 'simplificerede' eksempel, at der faktisk godt kan være
> mere end en linie med samme kombination af Navn + nummer (fordi der er
> andre felter i tabellen):
>
> >> Navn Nummer
> >> Peter 5
> >> Jens 5
> >> Peter 6
> >> Jens 5
> >> Peter 12
> >> Anders 4
> >> Jens 6
>
> Og det betyder, at der godt kan være (i dette tilfælde) 3, men ikke de
> tre unikke. I ovennævnte har Jens 5,5,6. Altså tre hit, men nr. 12 mangler.

Nu du skriver at det er længe siden, så er det også længe siden at jeg
postede min kommentar om at det burde virke hvis du benytter distinct.


select * from test;
name | id
------+----
Bent | 1
Bent | 2
Ole | 1
Ole | 1
(4 rows)

select name, count(distinct id) from test group by name;
name | count
------+-------
Bent | 2
Ole | 1
(2 rows)

(Testet på postgresql.)

At lave resten vil jeg lade være op til læseren

Mvh. Michael.

Kristian Damm Jensen (18-06-2007)
Kommentar
Fra : Kristian Damm Jensen


Dato : 18-06-07 15:44

Michael Zedeler wrote:
> Leif Neland wrote:
>> Gert Krabsen wrote:
>>> Jeg har en tabel, der (meget forenklet) ser sådan ud:
>>>
>>> Navn Nummer
>>> Peter 5
>>> Jens 5
>>> Peter 6
>>> Peter 12
>>> Anders 4
>>> Jens 6
>>>
>>> Men hvis jeg gerne vil have alle navne, der har _alle_ tre numre 5
>>> ,6, 12 (I dette tilfælde er resultatet Peter
>>>
>>> ..hvordan gør jeg lettest det???
>>
>> Man kunne også lave
>> select a.navn from tbl a
>> inner join tbl b using (navn)
>> inner join tbl c using(navn)
>> where a.nummer=5
>> and b.nummer=6
>> and c.nummer=12
>>
>> Men om det er mere eller mindre effektivt end den anden metode, der
>> er givet, ved jeg ikke.
>>
>> Den anden metode ser ihvertfald mere elegant ud...
>
> Join-metoden ovenfor er meget dyr.

Det kommer bestemt an på, hvilke index der er på tabellen. Med et index på
navn, vil det ikke kræve meget mere end et enkelt tablescan.

--
Venlig hilsen /Best regards
Kristian Damm Jensen



Michael Zedeler (18-06-2007)
Kommentar
Fra : Michael Zedeler


Dato : 18-06-07 21:18

Kristian Damm Jensen wrote:
> Michael Zedeler wrote:
>> Leif Neland wrote:
>>> Gert Krabsen wrote:
>>>> Jeg har en tabel, der (meget forenklet) ser sådan ud:
>>>>
>>>> Navn Nummer
>>>> Peter 5
>>>> Jens 5
>>>> Peter 6
>>>> Peter 12
>>>> Anders 4
>>>> Jens 6
>>>>
>>>> Men hvis jeg gerne vil have alle navne, der har _alle_ tre numre 5
>>>> ,6, 12 (I dette tilfælde er resultatet Peter
>>>>
>>>> ..hvordan gør jeg lettest det???
>>> Man kunne også lave
>>> select a.navn from tbl a
>>> inner join tbl b using (navn)
>>> inner join tbl c using(navn)
>>> where a.nummer=5
>>> and b.nummer=6
>>> and c.nummer=12
>>>
>>> Men om det er mere eller mindre effektivt end den anden metode, der
>>> er givet, ved jeg ikke.
>>>
>>> Den anden metode ser ihvertfald mere elegant ud...
>> Join-metoden ovenfor er meget dyr.
>
> Det kommer bestemt an på, hvilke index der er på tabellen. Med et index på
> navn, vil det ikke kræve meget mere end et enkelt tablescan.

Jeg tvivler kraftigt på at et mangedobbelt join med passende kriteriner
nogen sinde vil kunne konkurrere med group by, da det er nogle helt
andre oplysninger, der skal holdes i hukommelsen, når databasen
behandler forespørgslen. Alene de boolske udtryk der specificerer at
alle værdierne skal være forskellige vil vokse hurtigt med antallet af
forskellige værdier, man kigger efter:

SELECT *
FROM tbl t1, tbl t2
WHERE t1.navn = t2.navn
AND t1.nummer <> t2.nummer

Det ser udskyldigt, men i næste trin bliver det til

SELECT *
FROM tbl t1, tbl t2, tbl t3
WHERE t1.navn = t1.navn
AND t1.navn = t2.navn
AND t2.navn = t3.navn
AND t1.nummer <> t2.nummer
AND t1.nummer <> t3.nummer
AND t2.nummer <> t3.nummer

og så

SELECT *
FROM tbl t1, tbl t2, tbl t3, tbl t4
WHERE t1.navn = t1.navn
AND t1.navn = t2.navn
AND t2.navn = t3.navn
AND t3.navn = t4.navn
AND t1.nummer <> t2.nummer
AND t1.nummer <> t3.nummer
AND t1.nummer <> t4.nummer
AND t2.nummer <> t3.nummer
AND t2.nummer <> t4.nummer
AND t3.nummer <> t4.nummer

og for blot 5 forskellige får man

SELECT *
FROM tbl t1, tbl t2, tbl t3, tbl t4, tbl t5
WHERE t1.navn = t1.navn
AND t1.navn = t2.navn
AND t2.navn = t3.navn
AND t3.navn = t4.navn
AND t4.navn = t5.navn
AND t1.nummer <> t2.nummer
AND t1.nummer <> t3.nummer
AND t1.nummer <> t4.nummer
AND t1.nummer <> t5.nummer
AND t2.nummer <> t3.nummer
AND t2.nummer <> t4.nummer
AND t2.nummer <> t5.nummer
AND t3.nummer <> t4.nummer
AND t3.nummer <> t5.nummer
AND t4.nummer <> t5.nummer

Antallet af kriterier i anden afdeling af det boolske udtryk vokser
geometrisk, så kigger man efter n forskellige rækker, skal man have
n(n-1) sammenligninger. Alene det i sig selv mener jeg er nok til at
erklære den strategi for død, men jeg kan ikke overskue om der er en
måde at få et lineært antal led i stedet?

Mvh. Michael.

Kristian Damm Jensen (19-06-2007)
Kommentar
Fra : Kristian Damm Jensen


Dato : 19-06-07 15:24

Michael Zedeler wrote:
> Kristian Damm Jensen wrote:
>> Michael Zedeler wrote:
>>> Leif Neland wrote:
>>>> Gert Krabsen wrote:
>>>>> Jeg har en tabel, der (meget forenklet) ser sådan ud:
>>>>>
>>>>> Navn Nummer
>>>>> Peter 5
>>>>> Jens 5
>>>>> Peter 6
>>>>> Peter 12
>>>>> Anders 4
>>>>> Jens 6
>>>>>
>>>>> Men hvis jeg gerne vil have alle navne, der har _alle_ tre numre 5
>>>>> ,6, 12 (I dette tilfælde er resultatet Peter
>>>>>
>>>>> ..hvordan gør jeg lettest det???
>>>> Man kunne også lave
>>>> select a.navn from tbl a
>>>> inner join tbl b using (navn)
>>>> inner join tbl c using(navn)
>>>> where a.nummer=5
>>>> and b.nummer=6
>>>> and c.nummer=12
>>>>
>>>> Men om det er mere eller mindre effektivt end den anden metode, der
>>>> er givet, ved jeg ikke.
>>>>
>>>> Den anden metode ser ihvertfald mere elegant ud...
>>> Join-metoden ovenfor er meget dyr.
>>
>> Det kommer bestemt an på, hvilke index der er på tabellen. Med et
>> index på navn, vil det ikke kræve meget mere end et enkelt tablescan.
>
> Jeg tvivler kraftigt på at et mangedobbelt join med passende
> kriteriner nogen sinde vil kunne konkurrere med group by, da det er
> nogle helt andre oplysninger, der skal holdes i hukommelsen, når
> databasen behandler forespørgslen.

Det kommer bestemt an på sammenhængen og det præcise indhold i det
pågældende join. I det konkrete eksempel ser jeg ingen grund til at tro at
det multiple join er tungt at udføre.

Konkret:

- Table scan af tbl instans a.
- Filtrering på a.nummer
- Indexeret opslag i tbl instans b
- Filtrering på b.nummer
- Indexeret opslag i tbl instans c
- Filtrering på c.nummer

Det er muligt de tre filtreringer alle kommer til sidst, men selv da vil det
ikke være nogen performancemæssig katastrofe.

Jeg prøver ikke at argumentere for at dette er den bedste løsning, men siger
blot at argument "det er performancemæssigt dyrt" ikke holder vand.

> Alene de boolske udtryk der
> specificerer at alle værdierne skal være forskellige vil vokse
> hurtigt med antallet af forskellige værdier, man kigger efter:
>
> SELECT *
> FROM tbl t1, tbl t2
> WHERE t1.navn = t2.navn
> AND t1.nummer <> t2.nummer

Det var heller ikke, hvad der var tale om.

Eksemplet indeholdt specifikke tal som hhv. t1.nummer, t2.nummer osv. skulle
være lig. Ikke noget problem.

<snip irrelevante eksempler>

--
Venlig hilsen /Best regards
Kristian Damm Jensen



Michael Zedeler (19-06-2007)
Kommentar
Fra : Michael Zedeler


Dato : 19-06-07 21:55

Kristian Damm Jensen wrote:
> Michael Zedeler wrote:
>> Kristian Damm Jensen wrote:
>>> Michael Zedeler wrote:
>>>> Leif Neland wrote:
>>>>> Gert Krabsen wrote:
>>>>>> Jeg har en tabel, der (meget forenklet) ser sådan ud:
>>>>>>
>>>>>> Navn Nummer
>>>>>> Peter 5
>>>>>> Jens 5
>>>>>> Peter 6
>>>>>> Peter 12
>>>>>> Anders 4
>>>>>> Jens 6
>>>>>>
>>>>>> Men hvis jeg gerne vil have alle navne, der har _alle_ tre numre 5
>>>>>> ,6, 12 (I dette tilfælde er resultatet Peter
>>>>>>
>>>>>> ..hvordan gør jeg lettest det???
>>>>> Man kunne også lave
>>>>> select a.navn from tbl a
>>>>> inner join tbl b using (navn)
>>>>> inner join tbl c using(navn)
>>>>> where a.nummer=5
>>>>> and b.nummer=6
>>>>> and c.nummer=12
>>>>>
>>>>> Men om det er mere eller mindre effektivt end den anden metode, der
>>>>> er givet, ved jeg ikke.
>>>>>
>>>>> Den anden metode ser ihvertfald mere elegant ud...
>>>> Join-metoden ovenfor er meget dyr.
>>> Det kommer bestemt an på, hvilke index der er på tabellen. Med et
>>> index på navn, vil det ikke kræve meget mere end et enkelt tablescan.
>> Jeg tvivler kraftigt på at et mangedobbelt join med passende
>> kriteriner nogen sinde vil kunne konkurrere med group by, da det er
>> nogle helt andre oplysninger, der skal holdes i hukommelsen, når
>> databasen behandler forespørgslen.
>
> Det kommer bestemt an på sammenhængen og det præcise indhold i det
> pågældende join. I det konkrete eksempel ser jeg ingen grund til at tro at
> det multiple join er tungt at udføre.
>
> Konkret:
>
> - Table scan af tbl instans a.
> - Filtrering på a.nummer
> - Indexeret opslag i tbl instans b
> - Filtrering på b.nummer
> - Indexeret opslag i tbl instans c
> - Filtrering på c.nummer
>
> Det er muligt de tre filtreringer alle kommer til sidst, men selv da vil det
> ikke være nogen performancemæssig katastrofe.

Det er lige min indvending og jeg er uenig med dig i at det ikke skulle
være nogen performancemæssig katastrofe. Jeg har temmelig svært ved at
se hvordan et flerdobbelt join af en tabel på sig selv ikke kan koste
dyrt - også med de korrekte indexes.

Men det er jo svært at afgøre uden flere konkrete oplysninger. Hvis der
aldrig vil være mere end nogle få tusinde rækker i tabellen, er det jo
temmelig akademisk.

Jeg synes at det er pudsigt at du argumenterer for en forespørgsel der
med stor sikkerhed ikke kan være hurtigere, end det jeg foreslår. Men
sådan er det selvfølgelig når man diskuterer teoretiske emner.

Desværre har jeg ikke rodet nok med performance tuning af databaser til
at kunne bidrage med noget særligt i den forbindelse. Den eneste
tommelfingerregel jeg virkelig går op i er at undgå mangedobbelte joins.

> Jeg prøver ikke at argumentere for at dette er den bedste løsning, men siger
> blot at argument "det er performancemæssigt dyrt" ikke holder vand.

Hvis du kan komme med et eksempel på at din forespørgsel performer lige
så godt som den jeg har foreslået, synes jeg at det er mere interessant
at diskutere videre.

> Det var heller ikke, hvad der var tale om.
>
> Eksemplet indeholdt specifikke tal som hhv. t1.nummer, t2.nummer osv. skulle
> være lig. Ikke noget problem.
>
> <snip irrelevante eksempler>

Det har du ret i.

Mvh. Michael.

Søg
Reklame
Statistik
Spørgsmål : 177579
Tips : 31968
Nyheder : 719565
Indlæg : 6409073
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste