Avatar billede jaspers_cool Nybegynder
19. juni 2006 - 20:04 Der er 20 kommentarer og
1 løsning

select en masse rækker, sorter og fravælg på en enkelt column

Jeg har en kæmpe liste over firmaer hvor jeg gerne vil hente deres ID, navn, CVR, addresse og ZIP kode. Desværre er et firma som f.eks. BlockBuster listet 25 gange fordi hver enkelt afdeling er listet med sin egen addresse.

Hver afdeling har dog det samme CVR nummer, så jeg vil egentlig blot gerne kun have én gang BlockBuster med i resultatet for min SELECT.

Hvordan kan jeg sortere distinct kun på CVR nummere?

Jeg har det her indtil videre:

SELECT
  COMPANY.COMPANY_ID,
  COMPANY.NAME,
  COMPANY.POSTAL_CODE,
  COMPANY.CVR,
  COMPANY.OWNER,
  COMPANY.TDC_ID
FROM
  COMPANY
WHERE
  (COMPANY.NUM_EMPLOYEES >= '100') AND
  (COMPANY.POSTAL_CODE BETWEEN '1000' AND '1165')

Jeg vil helst gerne gøre det hele i en enkelt query, bare for at være besværlig :-) (og fordi CRM systemet er irriterende).

Hjæælp, er jeg helt gal på den?
Avatar billede fun22 Nybegynder
19. juni 2006 - 20:11 #1
Prøv med:

SELECT DISTINCT
  COMPANY.COMPANY_ID,
  COMPANY.NAME,
  COMPANY.POSTAL_CODE,
  COMPANY.CVR,
  COMPANY.OWNER,
  COMPANY.TDC_ID
FROM
  COMPANY
WHERE
  (COMPANY.NUM_EMPLOYEES >= '100') AND
  (COMPANY.POSTAL_CODE BETWEEN '1000' AND '1165')
Avatar billede jumper Nybegynder
20. juni 2006 - 09:04 #2
Jeg arbejder med jasper og det hjalp ikke - da der er forskellige addresser er de jo alle overordnet DISTINCT, men der skal vælges én fra hver unik CVR.

Som et eksempel, så kan dataene se sådan her ud:

id    name    cvr

1    TDC    666
2    BlockBuster    1111
3    BlockBuster    1111
4    BlockBuster    1111
5    T-Hansen    8888
6    BlockBuster    1111

Lige nu bliver der returneret alle records (1-6), men det ønskede resultat skal kun være 1, 2 og 5:

id    name    cvr

1    TDC    666
2    BlockBuster    1111
5    T-Hansen    8888

Det er egentlig ligegyldigt hvilken BlockBuster der returneres :-)
Avatar billede thrytter Nybegynder
20. juni 2006 - 11:05 #3
SELECT
  COMPANY.COMPANY_ID,
  COMPANY.NAME,
  COMPANY.CVR
FROM
  COMPANY
GROUP BY
  COMPANY.CVR,
  COMPANY.COMPANY_ID,
  COMPANY.NAME

skulle give firmaoversigten. En vilkårlig firmaadresse kunne udtrækkes som en subquery i select delen.

Burde lave lidt om på designet men det er nok ikke helt ligetil.
Avatar billede thrytter Nybegynder
20. juni 2006 - 11:17 #4
Glem min sidste kommentar - virker ikke helt som beskrevet.
Avatar billede ux226 Nybegynder
20. juni 2006 - 13:17 #5
DISTINCT har kun effekt på det umiddelbart efterfølgende felt, så det I skal bruge er nærmere:

SELECT
  DISTINCT COMPANY.CVR,
  COMPANY.COMPANY_ID,
  COMPANY.NAME,
  COMPANY.POSTAL_CODE,
  COMPANY.OWNER,
  COMPANY.TDC_ID
FROM
  COMPANY
WHERE
  (COMPANY.NUM_EMPLOYEES >= '100') AND
  (COMPANY.POSTAL_CODE BETWEEN '1000' AND '1165')

Det burde virke, skulle jeg mene.
Avatar billede jaspers_cool Nybegynder
20. juni 2006 - 14:42 #6
ux226

Distinct har effekt på alle selectede rows.
Det virker i hvertfald ikke.
Avatar billede thrytter Nybegynder
20. juni 2006 - 15:16 #7
Ved ikke lige om dette virker i mySQL - virker i MSSQL

SELECT
  COMPANY.CVR,
  COMPANY.NAME,
  (
    SELECT  top 1 C.COMPANY_ID
    FROM    COMPANY C
    WHERE    C.CVR = COMPANY.CVR
    ORDER BY C.ID
  ) As COMPANY_ID,
  (
    SELECT  top 1 C.POSTAL_CODE
    FROM    COMPANY C
    WHERE    C.CVR = COMPANY.CVR
    ORDER BY C.ID
  ) As POSTAL_CODE
FROM
  COMPANY
WHERE    
  (COMPANY.POSTAL_CODE BETWEEN 1000 AND 1165)
GROUP BY
  COMPANY.CVR,
  COMPANY.NAME
HAVING SUM(COMPANY.NUM_EMPLOYEES) >= 100

Medtager kun firmaer med afdelinger i området 1000 og 1165, og med over 100 ansatte ialt.
Avatar billede hjochums Nybegynder
20. juni 2006 - 21:27 #8
Hvis du har 25 adresser på et CVR nummer, hvilken en af adreserne skal du så bruge?

Hvis adressen er ligemeget er det vel bare en GROUP BY på cvr-nummeret.
Avatar billede thrytter Nybegynder
20. juni 2006 - 21:56 #9
Kan ikke nøjes med GROUP BY COMPANY.CVR hvis adressen skal udtrækkes direkte, da denne (adressen og andre kolonner) også skal medtages i GROUP BY - gætter på at dette også er kravet i MySQL
Avatar billede arne_v Ekspert
20. juni 2006 - 22:09 #10
faktisk ikke - en mystisk feature i MySQL er at man godt kan angive
ikke aggregerede funktioner i select listen som ikke er i GROUP BY, saa
tager MySQL en tilfaeldig vaerdi
Avatar billede thrytter Nybegynder
20. juni 2006 - 22:21 #11
Ok, så lærte jeg også lidt om MySQL - burde måske installere tingesten (igen)
Avatar billede arne_v Ekspert
21. juni 2006 - 01:58 #12
et andet forslag:

SELECT
  C1.COMPANY_ID,
  C1.NAME,
  C1.POSTAL_CODE,
  C1.CVR,
  C1.OWNER,
  C1.TDC_ID
FROM
  COMPANY C1
WHERE
  (C1.NUM_EMPLOYEES >= '100') AND
  (C1.POSTAL_CODE BETWEEN '1000' AND '1165') AND
  (C1.COMPANY_ID IN (SELECT MIN(C2.COMPANY_ID) FROM COMPANY C2 WHERE C2.CVR=C1.CVR))
Avatar billede hjochums Nybegynder
21. juni 2006 - 08:00 #13
Nej, du behøver ikke have samme felter i select listen, som i group by listen.

Det betyder bare at den tager en tilfældig række (adresse) blandt de grupperede.

Derfor ville jeg gerne vide hvilken adresse du gerne ville have :)

SELECT
  COMPANY.COMPANY_ID,
  COMPANY.NAME,
  COMPANY.POSTAL_CODE,
  COMPANY.CVR,
  COMPANY.OWNER,
  COMPANY.TDC_ID
FROM
  COMPANY
WHERE
  (COMPANY.NUM_EMPLOYEES >= '100') AND
  (COMPANY.POSTAL_CODE BETWEEN '1000' AND '1165')
GROUP BY COMPANY.CVR
Avatar billede jumper Nybegynder
21. juni 2006 - 11:48 #14
arne_v, whee - dit forslag virker og returnerer kun én BlockBuster ud af de mange som har samme CVR. Det eneste negative er at den tager meget lang tid at køre - før var opslaget på under et sekund, nu er det "41 rows fetched (106,39 sec)" når jeg kører en query. Er der nogen måde at optimere det på?

hjochums, det er faktisk ligegyldigt hvilken af addresserne der vælges - der skal blot kun vælges ét firma for hver gang der er flere ens CVR numre.
Avatar billede arne_v Ekspert
21. juni 2006 - 13:28 #15
en subselect hvor subselect bruger noget fra den egentlige select er en tung sag at køre

har du index på CVR feltet ?
Avatar billede jaspers_cool Nybegynder
21. juni 2006 - 14:28 #16
Hej Arne, din sql virkede perfekt efter jeg smed en index på cvr.
tak for alle forslag.

smider du et svar arne_v
Avatar billede thrytter Nybegynder
21. juni 2006 - 14:55 #17
Syntes ikke, at jeg kan få sql'en fra arne_v til at stemme.

Hvis du har følgende BlockBuster's (sidste kolonne skulle være POSTAL_CODE)
2    BlockBuster    1111  5000
3    BlockBuster    1111  6000
4    BlockBuster    1111  7000
5    BlockBuster    1111  8000

og laver søgning på POSTAL_CODE mellem 7500 og 8500 - giver det intet resultat, da Id'et på 5 ikke findes i
  (C1.COMPANY_ID IN (SELECT MIN(C2.COMPANY_ID) FROM COMPANY C2 WHERE C2.CVR=C1.CVR))

Tager jeg helt fejl?
Avatar billede arne_v Ekspert
21. juni 2006 - 14:57 #18
kommer her
Avatar billede arne_v Ekspert
21. juni 2006 - 15:02 #19
nej - det er vist rigtigt - de 2 betingelser skal nok med i sub select'en
Avatar billede hjochums Nybegynder
21. juni 2006 - 15:25 #20
Burde kunne lade sig gøre med en GROUP BY istedet subselects er langsome..

SELECT
  COMPANY.COMPANY_ID,
  COMPANY.NAME,
  COMPANY.POSTAL_CODE,
  COMPANY.CVR,
  COMPANY.OWNER,
  COMPANY.TDC_ID
FROM
  COMPANY
GROUP BY COMPANY.CVR
HAVING
  (COMPANY.NUM_EMPLOYEES >= '100') AND
  (COMPANY.POSTAL_CODE BETWEEN '1000' AND '1165')
Avatar billede jaspers_cool Nybegynder
22. juni 2006 - 09:48 #21
ja group by var også det første jeg tænkte på, men det virker af en eller anden grund ikke i crm systemet.
Men tak for alle svar.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester