[SQL] ORDER BY vraagje?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Ghost-X
  • Registratie: Mei 2002
  • Laatst online: 08-09 08:37
Ik heb een sql sorteer vraagje waarvan ik niet direct een oplossing kan vinden, ook is mijn sql kennis beneden pijl uiteraard :-)

De ORDER BY kent de ASC en DESC, nu wil ik deze niet gebruiken maar vooraf een volgorde ingeven. Ik heb een veld waarvan de waarden 1 , 2 , 3 of 4 kan zijn.
Mijn idee was zoiets als:

ORDER BY veld('2','3','4','1')

Dit is echter niet mogelijk, is hier wel een mogelijkheid voor?

The one you cant see...


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Zoek in de manual naar CASE WHEN.

{signature}


Acties:
  • 0 Henk 'm!

  • zwippie
  • Registratie: Mei 2003
  • Niet online

zwippie

Electrons at work

In mysql sorteert een ENUM volgens mij op de volgorde die je in je ENUM definitie opgeeft. Als je dus een ENUM('2','3','4','1') gebruikt als kolomtype zou het moeten kunnen.

How much can you compute with the "ultimate laptop" with 1 kg of mass and 1 liter of volume? Answer: not more than 10^51 operations per second on not more than 10^32 bits.


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

zwippie schreef op dinsdag 08 december 2009 @ 12:50:
In mysql sorteert een ENUM volgens mij op de volgorde die je in je ENUM definitie opgeeft. Als je dus een ENUM('2','3','4','1') gebruikt als kolomtype zou het moeten kunnen.
Zelfs als dat zo is, is het een vieze hack. Sowieso kennen niet alle databaseservers een enumtype, en de kans dat het overal zo geïmplementeerd is als in MySQL is nog eens veel kleiner. CASE ... WHEN-contructies zijn een stuk leesbaarder en meer portable.

Los daarvan: Waar hoort mijn topic? Dit is een praktisch programmeerprobleem, geen ontwerpkwestie. SEA>>PRG

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • zwippie
  • Registratie: Mei 2003
  • Niet online

zwippie

Electrons at work

NMe schreef op dinsdag 08 december 2009 @ 12:54:
[...]

Zelfs als dat zo is, is het een vieze hack. Sowieso kennen niet alle databaseservers een enumtype, en de kans dat het overal zo geïmplementeerd is als in MySQL is nog eens veel kleiner. CASE ... WHEN-contructies zijn een stuk leesbaarder en meer portable.
Heb je gelijk in, maar de ENUM was het eerste dat bij me opkwam. ;)

How much can you compute with the "ultimate laptop" with 1 kg of mass and 1 liter of volume? Answer: not more than 10^51 operations per second on not more than 10^32 bits.


Acties:
  • 0 Henk 'm!

  • Ghost-X
  • Registratie: Mei 2002
  • Laatst online: 08-09 08:37
NMe schreef op dinsdag 08 december 2009 @ 12:54:
[...]

Zelfs als dat zo is, is het een vieze hack. Sowieso kennen niet alle databaseservers een enumtype, en de kans dat het overal zo geïmplementeerd is als in MySQL is nog eens veel kleiner. CASE ... WHEN-contructies zijn een stuk leesbaarder en meer portable.

Los daarvan: Waar hoort mijn topic? Dit is een praktisch programmeerprobleem, geen ontwerpkwestie. SEA>>PRG
Excuus niet goed gelezen..

Het lukt me niet dit te verweken in de ORDER BY sectie heeft iemand een klein voorbeeld??

The one you cant see...


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online

{signature}


Acties:
  • 0 Henk 'm!

  • Ghost-X
  • Registratie: Mei 2002
  • Laatst online: 08-09 08:37
Ja heb ik gedaan maar hier vindt ik geen antwoord op mijn vraag. Wat ik veel vind is een CASE WHEN om te bepalen op welke kolom er gesorteerd moet worden met behulp van een CASE statement.
Ik heb een kolom waarvan ik op de waarde wil sorteren de waarde kan 1 t/m 4 zijn maar ik wil ze niet alleen ASC of DESC sorteren maar ook bijv. 3,4,2,1......

The one you cant see...


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Als je numerieke waardes in de THEN term zet, sorteer je daarop. ;)

{signature}


Acties:
  • 0 Henk 'm!

  • Asator
  • Registratie: December 2009
  • Laatst online: 12-02-2024
Als je MySQL gebruikt zat je er toch al aardig dicht bij.

Als je enkel de waardes 1, 2, 3, 4 hebt in je tabel zal je die WHERE niet hoeven te gebruiken.
Zo te zien had je alleen niet aangegeven op welke veld hij moet sorteren.

SQL:
1
2
3
4
SELECT id
FROM tabel
WHERE id IN (1, 2, 3, 4)
ORDER BY FIELD(id, 2, 3, 4, 1)


Als je een andere database gebruikt, of als je wilt dat het voor verschillende databases werkt, kan je zoals eerder al gezegd is een CASE WHEN gebruiken.

SQL:
1
2
3
4
5
6
7
8
SELECT id
FROM tabel
WHERE id IN (1, 2, 3, 4)
ORDER BY CASE
    id when 2 then 1
        when 3 then 2
        when 4 then 3
        when 1 then 4 end


Nou heb ik niet veel verstand van hoe efficiënt al die verschillende manieren zijn, maar ik vind persoonlijk dat de eerste er netter uit ziet.

Acties:
  • 0 Henk 'm!

  • Leftblank
  • Registratie: Juni 2004
  • Laatst online: 13:51
Mocht je de waarden ooit nog (on the fly?) willen veranderen dan zou ik zelf voor een extra tabel gaan waarop je gewoon per id een 'sortvalue' opgeeft en daar vervolgens op sorteert. Ik durf niet te zeggen hoe dit zit qua performance tov. dingen als 'n switch of enum, maar indien nodig zit je wel met een flexibeler systeem wat ook nog vrij leesbaar blijft ;).

SQL:
1
2
3
4
SELECT *
FROM tabel
JOIN tabel_ordening ON tabel.veld = tabel_ordening.veld
ORDER BY tabel_ordening.sortvalue

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
@leftblank : yikes, dat vind ik zo ongeveer 1 vd ranzigste oplossingen die ik maar kan bedenken, een kolom in een bestaande tabel erbij ok, absoluut niet netjes, maar als je het later uitbreidt blijft er overzicht in de chaos wmb

Met een extra tabel en na verloop van tijd meerdere alternatieve sorteringen krijg ik toch echt het idee dat er mega-chaos gaat ontstaan. Ik zou in zo'n geval of voor een case structuur gaan ( indien weinig waardes ) of gewoon doeg zeggen tegen de normalisatie voor dit stukje

Acties:
  • 0 Henk 'm!

  • Leftblank
  • Registratie: Juni 2004
  • Laatst online: 13:51
Gomez12 schreef op woensdag 09 december 2009 @ 00:00:
@leftblank : yikes, dat vind ik zo ongeveer 1 vd ranzigste oplossingen die ik maar kan bedenken, een kolom in een bestaande tabel erbij ok, absoluut niet netjes, maar als je het later uitbreidt blijft er overzicht in de chaos wmb
Op die manier kun je dus zodra je de volgorde wil aanpassen en zooitje UPDATE's door je DB trekken, imo is een losse tabel dan toch nog de nettere keuze. Zodra je op meerdere velden wilt gaan sorteren zul je alsnog wel naar een slimmere query toe moeten, maar imo is dat wel de 'lesser evil' optie dan je data zelf gaan vervuilen met een sortvalue, zeker wanneer dit variabel zou zijn is dat wel vragen om problemen.

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Leftblank: dat soort sorteringen die kunnen wisselen worden meestal gerealiseerd zonder externe tabel, want die externe tabel zou toch alleen maar resulteren in een één op één-relatie, da's gewoon zonde van de join. :P

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Leftblank
  • Registratie: Juni 2004
  • Laatst online: 13:51
NMe schreef op woensdag 09 december 2009 @ 01:16:
Leftblank: dat soort sorteringen die kunnen wisselen worden meestal gerealiseerd zonder externe tabel, want die externe tabel zou toch alleen maar resulteren in een één op één-relatie, da's gewoon zonde van de join. :P
Dat ligt een beetje aan het soort data natuurlijk; als ik de TS lees dan maak ik daar niet uit op dat 't gaat om 'n één-op-één relatie tussen de data en volgorde, wanneer er dus meerdere rows zijn met dezelfde 'veld' waarde dan zou een extra tabel voor de volgorde dus nog best een redelijk genormaliseerde oplossing kunnen geven. Mocht het wel om zo'n basic relatie gaan dan is een join natuurlijk hopeloos. ;)

Acties:
  • 0 Henk 'm!

  • Ghost-X
  • Registratie: Mei 2002
  • Laatst online: 08-09 08:37
SQL:
1
2
3
4
5
6
7
8
SELECT id
FROM tabel
WHERE id IN (1, 2, 3, 4)
ORDER BY CASE
    id when 2 then 1
        when 3 then 2
        when 4 then 3
        when 1 then 4 end


Nou heb ik niet veel verstand van hoe efficiënt al die verschillende manieren zijn, maar ik vind persoonlijk dat de eerste er netter uit ziet.
Dank voor de reactie's.
Met bovenstaande code is het gelukt.

Maar ( ja er is een maar), ik heb de query uitgebreid met 2 UNIONS en krijg de volgende foutmelding.

Msg 104, Level 16, State 1, Line 1
ORDER BY items must appear in the select list if the statement contains a UNION, INTERSECT or EXCEPT operator.


Het item wat ik gebruik in de ORDER BY wordt ook geselecteerd in alle drie de select statements..
Is het niet mogelijk een CASE te gebruiken icm UNIONS??

The one you cant see...


Acties:
  • 0 Henk 'm!

  • Asator
  • Registratie: December 2009
  • Laatst online: 12-02-2024
Ghost-X schreef op vrijdag 11 december 2009 @ 15:06:
[...]


Dank voor de reactie's.
Met bovenstaande code is het gelukt.

Maar ( ja er is een maar), ik heb de query uitgebreid met 2 UNIONS en krijg de volgende foutmelding.

Msg 104, Level 16, State 1, Line 1
ORDER BY items must appear in the select list if the statement contains a UNION, INTERSECT or EXCEPT operator.


Het item wat ik gebruik in de ORDER BY wordt ook geselecteerd in alle drie de select statements..
Is het niet mogelijk een CASE te gebruiken icm UNIONS??
Als je UNIONS gebruikt dan moet je er rekening mee houden dat de eerste SELECT die je maakt de 'select list' is en bij je laatste SELECT je de ORDER BY stopt. De kolom waarop je sorteert moet dan in je eerste SELECT voorkomen.

Misschien dat het helpt als je de query post die je tot zover gemaakt hebt.

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Haakjes om de complete reut, die order by eronder, hatsikidee.

{signature}


Acties:
  • 0 Henk 'm!

  • Ghost-X
  • Registratie: Mei 2002
  • Laatst online: 08-09 08:37
Ik zal de code even posten:


SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
SELECT 
P3.ID, 
P3.Row, 
P3.Pos, 
P3.Lvl, 
P3.Width, 
P3.MaxDiameter, 
P3.ProductType, 
(CASE WHEN P1.TopLoad > P2.TopLoad THEN P2.TopLoad ELSE P1.TopLoad END) AS MaxLoad 

FROM 
UA#PositionData3 AS P1 LEFT OUTER JOIN 
UA#PositionData3 AS P2 ON P1.Row = P2.Row AND P1.Pos = P2.Pos - 1 AND P1.Lvl = P2.Lvl LEFT OUTER JOIN 
UA#PositionData3 AS P3 ON P2.Row = P3.Row AND P2.Pos = P3.Pos + 1 AND P2.Lvl = P3.Lvl - 1 

WHERE 
P1.Type = 3 AND 
P2.Type = 3 AND 
P1.Enable = 1 AND 
P2.Enable = 1 AND 
P1.State = 1 AND 
P2.State = 1  AND 
P1.DigOut = 0 AND 
P2.DigOut = 0 AND 
P3.Type = 3 AND 
P3.Enable = 1 AND 
P3.State = 0 AND 
P3.Res = 0 AND 
(P3.Block = 0 OR P3.Block = 1) AND 
P3.Width =1290 AND 
P3.MaxDiameter = 1425 AND 
P3.Lvl = 2 AND 
(P3.ProductID = '' OR P3.ProductID = 0) AND 
(P3.ProductType = 0 OR P3.ProductType = 1) 

UNION
 
SELECT 
P3.ID, 
P3.Row, 
P3.Pos, 
P3.Lvl, 
P3.Width, 
P3.MaxDiameter, 
P3.ProductType, 
(CASE WHEN P1.TopLoad > P2.TopLoad THEN P2.TopLoad ELSE P1.TopLoad END) AS MaxLoad 

FROM 
UA#PositionData3 AS P1 LEFT OUTER JOIN 
UA#PositionData3 AS P2 ON P1.Row = P2.Row AND P1.Pos = P2.Pos - 1 AND P1.Lvl = P2.Lvl LEFT OUTER JOIN 
UA#PositionData3 AS P3 ON P2.Row = P3.Row AND P2.Pos = P3.Pos + 1 AND P2.Lvl = P3.Lvl - 1 LEFT OUTER JOIN 
UA#PositionData3 AS P4 ON P4.Row = P3.Row AND P4.Pos = P3.Pos LEFT OUTER JOIN 
UA#PositionData3 AS P5 ON P5.Row = P3.Row AND P5.Pos = P3.Pos + 1 LEFT OUTER JOIN 
UA#PositionData3 AS P6 ON P6.Row = P3.Row AND P6.Pos = P3.Pos + 2 

WHERE 
P1.Type = 3 AND 
P2.Type = 3 AND 
P1.Enable = 1 AND 
P2.Enable = 1 AND 
P1.State = 1 AND 
P2.State = 1  AND 
P1.DigOut = 0 AND 
P2.DigOut = 0 AND 
P3.Type = 3 AND 
P3.Enable = 1 AND 
P3.State = 0 AND 
P3.Res = 0 AND 
(P3.Block = 0 OR P3.Block = 1) AND 
P3.Width =1290 AND 
P3.MaxDiameter = 1425 AND 
P4.Type = 3 AND 
P4.Lvl = 1 AND 
P4.DigOut = 0 AND 
P5.Type = 3 AND 
P5.Lvl = 1 AND 
P5.DigOut = 0 AND 
P6.Type = 3 AND 
P6.Lvl = 1 AND 
P6.DigOut = 0 AND 
P3.Lvl = 3 AND 
(P3.ProductID = '' OR P3.ProductID = 0) AND 
(P3.ProductType = 0 OR P3.ProductType = 1) 

UNION
 
SELECT 
P3.ID, 
P3.Row, 
P3.Pos, 
P3.Lvl, 
P3.Width, 
P3.MaxDiameter, 
P3.ProductType, 
120000 AS MaxLoad 
FROM 
UA#PositionData3 AS P3 

WHERE 
P3.Type = 3 AND 
P3.Enable = 1 AND 
P3.State = 0 AND 
P3.Res = 0 AND 
(P3.Block = 0 OR P3.Block = 1) AND 
P3.Lvl = 1 AND 
(P3.ProductType = 0 OR P3.ProductType = 1) AND 
P3.Width =1290 AND 
P3.MaxDiameter = 1425 

ORDER BY CASE P3.Lvl 
    WHEN 1 THEN 3
    WHEN 2 THEN 1
    WHEN 3 THEN 2 END


Wanneer ik de ORDER BY gebruik zonder de UNIONS werkt het wel.. 8)7

[ Voor 197% gewijzigd door Ghost-X op 11-12-2009 16:23 ]

The one you cant see...


Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Queries worden niet door de database verwerkt zoals je ze schrijft.
De database begint met selectie (FROM/JOIN/WHERE, niet de select clause zelf), dan groeperen (GROUP BY/HAVING), dan projectie (Je velden tussen SELECT en FROM) en als laatste sorteren. Dat sorteren vind plaats op het eindresultaat. Anders zou je part 1 oplopende kunnen sorteren en part 2 aflopend en dan krijg je heel rare resultaten.

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Ghost-X schreef op vrijdag 11 december 2009 @ 16:19:
Ik zal de code even posten:
[...]
Voutloos schreef op vrijdag 11 december 2009 @ 16:05:
Haakjes om de complete reut, die order by eronder, hatsikidee.
Of zie hier... ;)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Ghost-X
  • Registratie: Mei 2002
  • Laatst online: 08-09 08:37
:'( :'(

Het zal aan mij liggen denk..

Ik heb zoals bovenstaand artikel aangeeft alle individuele SELECT's tussen ( ) gezet. Krijg nog steeds dezelfde foutmelding.

Ik heb het GEHEEL tussen ( ) gezet met daaronder de ORDER BY, nog steeds dezeflde melding.

Ik heb de SELECT's tussen haakjes gezet EN het geheel ook nog eens maar weer die foutmelding....

:'( :'(

The one you cant see...


Acties:
  • 0 Henk 'm!

  • Asator
  • Registratie: December 2009
  • Laatst online: 12-02-2024
This kind of ORDER BY cannot use column references that include a table name (that is, names in tbl_name.col_name format). Instead, provide a column alias in the first SELECT statement and refer to the alias in the ORDER BY. (Alternatively, refer to the column in the ORDER BY using its column position. However, use of column positions is deprecated.)

Also, if a column to be sorted is aliased, the ORDER BY clause must refer to the alias, not the column name. The first of the following statements will work, but the second will fail with an Unknown column 'a' in 'order
Als je dat stukje is goed leest.

Als ik het goed begrijp mag je geen kolom gebruiken waar een tabel naam in zit, in jouw geval dus P3 in P3.Lvl. Van die kolom moet je in je eerste select een alias maken, en die alias moet je weer in je ORDER BY gebruiken.

Acties:
  • 0 Henk 'm!

  • Ghost-X
  • Registratie: Mei 2002
  • Laatst online: 08-09 08:37
Opgelost mensen dank voor alle reactie's

uiteindelijk heb ik het volgende gedaan..

SQL:
1
2
3
4
5
6
7
8
9
10
11
SELECT * FROM 

(

/* Alle bovenstaande code*/

) 

AS ResTable

ORDER BY CASE Lvl WHEN 1 THEN 3 WHEN 2 THEN 1 WHEN 3 THEN 2 END

[ Voor 4% gewijzigd door Ghost-X op 13-12-2009 16:36 ]

The one you cant see...

Pagina: 1