Sortowanie bazy według ceny w MySQL

Witam serdecznie,

Mam taką tabelę:

 

CREATE TABLE IF NOT EXISTS `produkty` (
  `bf_id` bigint(20) unsigned NOT NULL,
  `nazwa` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
  `cena_netto` decimal(9,2) DEFAULT '0.00',
  `cena_promocyjna` decimal(9,2) DEFAULT '0.00',
) ENGINE=MyISAM AUTO_INCREMENT=33 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

 

 

W kolumnach cena_netto i cena_promocyjna mam ceny.

Potrzebuję zapytania który posortuje mi produkty na zasadzie sortowania:

a) jeśli produkt nie ma przypisanej cena_promocyjna - to bierzemy pod uwagę cenę tradycyjną,

b) jeśli produkt ma cena_promocyjna - to bierzemy pod uwagę tą cenę…

 

Da się coś takiego zrobić?

 

Northwest

stwórz sobie 3 pole aktualna_cena i ustawiaj je triggerem w zależności tak jak opisałeś. Sortuj po nim.

dziękuję :) 

A gdybym chciał wyświetlić ostatnio dodane 10 produktów i posortować je według nazwy?

 

Chodzi o sortowanie tylko między tymi ostatnio dodanymi rekordami - a nie całością bazy :slight_smile:

W bazie nie masz daty. Musisz dodać pole z datą wstawienia produktu aby w ogóle było to możliwe.

Co do samego samego sortowania, to logicznie jest to niemożliwe jeśli chodzi o ORDER BY, ponieważ najpierw musisz posortować, aby następnie odciąć 10 “górnych” rekordów. Więc sortowane jest całość. To co możesz zrobić, aby proces zoptymalizować, to nałożyć na pole daty indeks, samo to powinno już dać ogromny boost w połączeniu z late row lookup. Jeśli to będzie za mało użyj BD, która oferuje trzymanie indeksów w RAM (odczyty w pamięci operacyjnej są szybsze, niż dyskowe), a jeśli to będzie za mało użyj indeksera np. Solr albo ElasticSearch.

Innym sposobem może być zmiana algorytmu, ale ma to sens tylko jeśli odczytów jest dużo więcej niż zapisów. To znaczy zapamiętać gdzieś np. w statycznym polu aplikacji datę 10 wiersza, a następnie przy dodaniu nowego przeliczać to globalne pole na nowo. Wszystkie odczyty będą korzystać z tego pola wybierając tylko te wiersze (WHERE) są większe od tego pola.

Nie musisz dodawać żadnego dodatkowego pola z aktualna cena.

 

select case cena_promocyjna when 0 then cena_netto else cena_promocyjna as cena

from produkty

order by case cena_promocyjna when 0 then cena_netto else cena_promocyjna