Zasadniczo mam kilka metadanych wygenerowanych przez użytkowników dla poszczególnych elementów. Metadane składają się z tytułu i odpowiedniej wartości. Jeden element może mieć jeden konkretny tytuł metadanych, a inny nie. Tak więc utworzenie nowej kolumny w mojej głównej tabeli wydaje się niewłaściwym podejściem, ponieważ nie chcę, aby każdy element miał te same tytuły metadanych.

Problem polega na tym, że chcę sortować według tych metadanych. Mogę łatwo wygenerować tabelę, w której metadane wyglądają jak kolejna kolumna, ale chcę posortować według tego. Aby zilustrować to, co mam:

Powiedz, że mam następujące stoły:

Items Table:
id | color
----------
0  | red
1  | pink
2  | orange

MetaData Table
itemId |     title     |     data
-----------------------------------------
   0        shape           round
   1   |    shape      |    square
   0   |    sound      |    LOUD!

Mogę łatwo napisać SQL i kod, aby wygenerować coś takiego z tych tabel:

id  |    color   |   shape    |   sound
--------------------------------------------
0   |    red     |   round    |   LOUD!
1   |    pink    |   square   |            
2   |   orange   |            |   

Tak więc podczas generowania, jeśli element nie ma tytułu metadanych, który wyświetlam, jest po prostu pusty. Chciałbym umożliwić użytkownikowi sortowanie według kształtu lub dźwięku i wyświetlanie tylko tych, które są puste na dole.

Mógłbym wprowadzić wszystkie dane, wygenerować tabele, a następnie posortować je w kodzie... ale... to nie byłoby w ogóle praktyczne dla setek wpisów, z którymi być może będę musiał pracować.

Czy można to zrobić w SQL (używam mysql, ale coś bardziej ogólnego byłoby lepsze, gdybym to zmienił)? Czy mój układ stołu jest po prostu niepraktyczny do tego / powinienem to zrobić w inny sposób (wolałbym nie zmieniać układu stołu).

Dzięki!

0
user1234814 27 luty 2012, 08:58

3 odpowiedzi

Najlepsza odpowiedź

Możesz umieścić puste wartości na dole za pomocą czegoś takiego:

select
  Items.id,
  Items.color,
  max(case when title = 'shape' then data else null end) as shape,
  max(case when title = 'sound' then data else null end) as sound
from Items left outer join MetaData
on Items.id = MetaData.itemId
group by Items.id, Items.color
order by
  case when shape is not null then 0 else 1 end,
  shape
0
Steve Kass 27 luty 2012, 09:53

Cóż, jeśli udało ci się zrobić ten pivot w mysql, to znaczy dodając shape jako kolumnę w zapytaniu, używasz instrukcji CASE lub IF.

Więc jedyne, co musisz zrobić, to przypisać im alias, a następnie uporządkować według tego aliasu.

Otóż to :)

0
Mosty Mostacho 27 luty 2012, 09:55

Jest problem z rozwiązaniem Steve'a Kassa. W każdym razie, po nieco większej lekturze tabel przestawnych i kilku eksperymentach, oto moje rozwiązanie robocze dla wszystkich zainteresowanych:

SELECT DISTINCT items.id, items.color, 
GROUP_CONCAT(CASE WHEN metaData.title = ? THEN metaData.data ELSE NULL END) AS metaDataSortItem FROM items 
LEFT OUTER JOIN metaData ON items.id=metaData.itemId 
GROUP BY items.id
ORDER BY metaDataSortItem ASC

Wygląda na to, że działa tak, jak się spodziewałem.

0
user1234814 16 marzec 2012, 07:59