Sortowanie warunkowe

Mam model Topic, z kolumnami (obydwie typu boolean) sticked i closed. Czy jest możliwość wyciągnięcia w jednym zapytaniu danych posortowanych tak, by w przypadku rekordów ze sticked = 1 rekordy z closed = 1 były “na górze”, natomiast w przypadku gdy sticked = 0, te z closed = 0 chcę mieć na dole. Dodam, że używam MySQL.

Nie do końca rozumiem jak to ma być posortowane. Masz 4 opcje:

a) sticked 1 closed 1
b) sticked 1 closed 0
c) sticked 0 closed 1
d) sticked 0 closed 0

W jakiej kolejności mają być wyciągnięte te rekordy? Może zrobić sortowanie po 2 kolumnach “sticked DESC closed DESC” wtedy kolejność będzie a b c d, możesz zrobić wirtualną kolumnę i zsumować sticked+closed i po tym posortować (wtedy a będzie pierwsze, d ostatnie, natomiast b i c w niewiadomej kolejności).

Chciałbym w takim wypadku, żeby były posortowane w kolejności: a) b) d) c).
Algorytm przedstawiać się powinien następująco: Sortujemy najpierw według “sticked” - te z jedynką dajesz na górę, de z 0 - na dół. Następnie Obydwie części - górną i dolną - sortujemy niejako oddzielnie według “closed” - tak, aby w części “dolnej” closed=1 były na dole, a w części górnej - na górze.

No to w takim razie sortujesz tak: “sticked DESC closed ASC”

A czy nie wtedy nie posortuje mi tego naszego przykładu w kolejności a) b) c) d)?

Ach, nie, posortuje jeszcze inaczej - będzie b) a) d) c), więc też źle… :expressionless:

Jeśli nikt nie wpadnie na nic lepszego - zawsze możesz zrobić dwa zapytania, jedno bierze Topic’i, które mają sticked = 1 i sortuję wg closed malejąco, a druga ma where(sticked: 0) i sortowanie wg closed rosnąco, a potem połączyć takie dwie tablice : ) Ale to już raczej ostateczność, dziwne sortowanie : ) Jeśli to forum, to myślę, że ‘sticked DESC closed ASC’ powinno wyglądać ok : )

Też na to wpadłem - ale właśnie chciałem to zrobić w jednym zapytaniu, dlatego zresztą tutaj napisałem. :wink:

ORDER BY sticked DESC, (sticked XOR closed) ASC

Nie mam tego teraz jak sprawdzić - ale widzę, dlaczego może działać. Że też wcześniej na to nie wpadłem. Dzięki! :wink:

Generalnie jeśli będziesz miał dane, które nie dają się tak ładnie binarnie sprowadzić do jednej wartości, możesz użyć konstrukcji w stylu:

SELECT * FROM clients ORDER BY (CASE WHEN id=7 THEN 1 ELSE 2 END), (CASE WHEN name LIKE 'Z%' THEN 1 ELSE 2 END );

Nie wiem jak MySQL, ale porządne bazy danych to rozumieją. :wink:

MySQL podobnej konstrukcji nie rozumiał, próbowałem. Chyba że robiłem nagminnie jakiś błąd składniowy, bo w temacie relacyjnych baz danych jestem relatywnie (nomen omen) nowy. :wink:

Zobacz tu: http://dev.mysql.com/doc/refman/5.6/en/control-flow-functions.html#operator_case

Wychodzi na to, że MySQL ma tę funkcję, choć bym się nie zdziwił, gdyby nie potrafił jej użyć w ORDER BY - jeśli tak, to możesz spróbować dodać ją do kolumn zwracanych przez SELECT, a potem odwołać się w ORDER BY do tej kolumny przez alias lub indeks numeryczny. Tu znów nie wiem co z tego MySQL potrafi… :frowning:

Generalnie to dyskusja akademicka, bo ten Twój problem dało się rozwiązać prostszą funkcją, ale ja bym w wolnej chwili spróbował wybadać ten przypadek (gdybym oczywiście miał zamiar kiedykolwiek pracować na MySQL :wink: )


Yaaahupii! To mój pierwszy ośmiobitowy post! :smiley: Rozgadałem się przez te 2 lata…