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-Key: 334803

Url: https://administrator.de/contentid/334803

Printed on: April 26, 2024 at 02:04 o'clock

Member: sabines
sabines Apr 11, 2017 at 06:41:39 (UTC)
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
Member: SeaStorm
SeaStorm Apr 11, 2017 at 06:49:23 (UTC)
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.
Member: em-pie
em-pie Apr 11, 2017 at 07:13:52 (UTC)
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
Member: Dirmhirn
Dirmhirn Apr 11, 2017 at 07:34:11 (UTC)
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
Member: AS-N00
AS-N00 Apr 11, 2017 at 07:54:10 (UTC)
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.
Member: SeaStorm
SeaStorm Apr 11, 2017 at 08:10:14 (UTC)
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
Member: AS-N00
AS-N00 Apr 11, 2017 at 09:05:33 (UTC)
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?
Member: SeaStorm
Solution SeaStorm Apr 11, 2017 updated at 10:39:36 (UTC)
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
Member: AS-N00
AS-N00 Apr 12, 2017 at 06:34:56 (UTC)
Goto Top
Oh man, ja klar, an ein extra Feld habe ich gar nicht gedacht, das lässt sich leicht umsetzen, danke!