as-n00
Goto Top

MySQL "order by" erst bestimmtes Wort, dann alphabetisch

Hallo,

ich möchte die Ausgabe eines Listings in einem Webshop so einstellen, dass er bei der Abfrage for der Sortierung noch was einfügt.

Also derzeit sieht es so aus:
order by p.products_quantity DESC, p.products_stock_int DESC, m.manufacturers_name ASC, p.products_ad_image_0 DESC, p.products_ordered DESC'  

Ich möchte aber vorher noch alle Artikel eines bestimmten Markenherstellers anzeigen lassen, in etwa:
products_name LIKE "Markenname%"   

Also irgend wie so:
order by products_name LIKE "Markenname%" DANACH order by p.products_quantity DESC, p.products_stock_int DESC, m.manufacturers_name ASC, p.products_ad_image_0 DESC, p.products_ordered DESC'  

Wäre für einen kleinen Hinweis dankbar.

Ciao

Content-ID: 334803

Url: https://administrator.de/forum/mysql-order-by-erst-bestimmtes-wort-dann-alphabetisch-334803.html

Ausgedruckt am: 24.12.2024 um 12:12 Uhr

sabines
sabines 11.04.2017 um 08:41:39 Uhr
Goto Top
Moin,

ich verstehe dein Problem nicht so ganz, aber wäre hier ein Ansatz für Dich:

http://stackoverflow.com/questions/3609166/mysql-order-by-like

Gruss
SeaStorm
SeaStorm 11.04.2017 um 08:49:23 Uhr
Goto Top
Hi

grundsätzlich lässt sich sowas per CASE lösen:

ORDER BY (CASE WHEN products_name = 'NIKE' THEN 1 ELSE 2 END),this ASC, that DESC


Aber:

Sowas ist sehr lahm, da es auf solche cases keine Indexe gibt.
Für sowas gibt es spezialisierte Dienste wie Elasticsearch, die sehr sehr mächtig sind, was sowas angeht.
em-pie
em-pie 11.04.2017 um 09:13:52 Uhr
Goto Top
Moin,

kann mich da sabines nur anschließen... irgendwie komische Frage.

Zunächst sortiert ein ORDER By die Attribute immer in der Reihenfolge, wie du sie angibst:
Beispiel:
 
... 
ORDER BY
  Gehalt Desc
  , Name
  , Vorname

Hier wird erst nach Gehalt absteigend sortiert, gibt es Leute, deren Gehalt gleich ist, wird dann nach Nachname aufsteigend sortiert. Heißen dann noch drei Leute Müller, die alle drei 2500€ verdienen, wird nach Vornamen aufsteigend sortiert.

Willst du den Namen Einschränken, wäre es wie folgt:
 
... 
WHERE
  Name like 'Mei%'  
ORDER BY
  Gehalt Desc
  , Name
  , Vorname
Somit werden nur diejenigen überhaupt angezeigt, deren Nachname mit Mei beginnt. Das wären dann alle Meiers, Meierschmidts,Meisters// Hier dann aber auch wieder zunächst nach Gehalt, dann nach Nachname und dann nach Vorname sortiert...

Gruß
em-pie
Dirmhirn
Dirmhirn 11.04.2017 um 09:34:11 Uhr
Goto Top
Hi,

denke das ist mit zwei SQL-Querries schneller und vor allem übersichtlicher.
Einmal fragst du die Markenartikel ab und dann alle anderen ohne den Markenartikeln.

Geht im Prinzip auch in SQL mit Union o.ä.

Aber du solltest testen was performanter ist. grad bei einem Webshop. Da hat die zwei SQL Lösung vll sogar noch einen Vorteil - du kannst die Markenartiekl einen Tick früher anzeigen.

sg Dirm
AS-N00
AS-N00 11.04.2017 um 09:54:10 Uhr
Goto Top
Ja, das hatte ich mir auch schon gedeacht, geht aber nicht, da die gesamte Query aus zig Teilen zusammengebaut wird.
je nachdem was der Kunde für Filter setzt wird da immer eine mehr oder weniger einzigartige Query erstellt.
Ich müsste dann das ganze verdoppeln, das ist IMHO nicht sehr performant.
SeaStorm
SeaStorm 11.04.2017 um 10:10:14 Uhr
Goto Top
ganz besonders wenn es um so gefilter, priorisierung, bossting etc geht: Elasticsearch mal ansehen!
Kann man viele tolle Dinge mit machen. Gewisse ergebnisse per Boosting nach vorne bringen, schreibfehler ausgleichen, ähnliche Wörter suchen/finden, Filtern nach Attributen etc etc.

Wenn ihr euren Shop ernst nehmt, werdet ihr damit viel Freude haben
AS-N00
AS-N00 11.04.2017 um 11:05:33 Uhr
Goto Top
Ich schaue mir das gerne mit Elasticsearch an, aber ich brauche die obige Sache nur kurzfristig für eine Aktion, daher würde mir eine rudimentäre Lösung erstmal reichen.

Ganz kapier ich das mit dem CASE nicht.

order by products_name LIKE "Markenname%" DANACH order by p.products_quantity DESC, p.products_stock_int DESC, m.manufacturers_name ASC, p.products_ad_image_0 DESC, p.products_ordered DESC'  

ist dann:

order by case when products_name LIKE "Markenname%" then 1  
when products_name NOT LIKE "Markenname%" then p.products_quantity DESC, p.products_stock_int DESC, m.manufacturers_name ASC, p.products_ad_image_0 DESC, p.products_ordered DESC'  

Passt doch so nicht, oder?
SeaStorm
Lösung SeaStorm 11.04.2017 aktualisiert um 12:39:36 Uhr
Goto Top
nein der ELSE Zweig muss eine 2 (oder halt >1) sein. Damit sortiert er dann immer den "1" wert nach oben um dann alle "2"er zu listen. Da aber nach der 1 ALLES der 2 entspricht, sortiert er innerhalb des 2er Blocks nach den weiteren Kriterien:

order by 
(case when 
products_name LIKE "Markenname%"   
then 1 ELSE 2 
END),
p.products_quantity DESC, p.products_stock_int DESC, m.manufacturers_name ASC, p.products_ad_image_0 DESC, p.products_ordered DESC'  


EDIT: Jetzt wo ich deine Abfrage so sehe, denke ich, es wäre für dich sinnvoller, eine weitere Spalte "Priorität"/"Boost" anzulegen und nach der zu sortieren. Diese Spalte befüllst du dann per Script periodisch nach deinen Kriterien. Darauf kannst du dann auch einen Index anlegen, was der Geschwindigkeit gut tut.
Üblicherweise macht man sich dann eine "Boost-Formel", der man seine Kriterien mitgibt, wie z.B
Hersteller "Nike" = Boostfaktor 1,8
Adidas = 1,6

Verfügbarkeit Ja: 1,2

Aktuelle Kollektion 2,1


usw

und dann rechnet man sich mit den Faktoren einen Boostwert aus, der in das Feld des Atikels kommt, nach dem man dann sortiert
AS-N00
AS-N00 12.04.2017 um 08:34:56 Uhr
Goto Top
Oh man, ja klar, an ein extra Feld habe ich gar nicht gedacht, das lässt sich leicht umsetzen, danke!