2010-03-21 20 views
18

Veritabanında iki tablo var:Dizi elemanları sırası ile dizi türü ile PostgreSQL JOIN, nasıl uygulanır?

CREATE TABLE items(
id SERIAL PRIMARY KEY, 
... some other fields 
); 

Bu tablo benzersiz bir kimlik ile birlikte gelen veri satırını içerir.

CREATE TABLE some_chosen_data_in_order(
id SERIAL PRIMARY KEY, 
id_items INTEGER[], 

);

Bu tablo dizi tipi alanı içeriyor. Her sıra, belirli sırayla items tablosundaki ID değerlerini içerir. Örneğin: {2,4,233,5}.

Şimdi, some_chosen_data_in_order tablosundan, some_chosen_data_in_order tablosundan seçilen satır için, dizi tipindeki öğeler için sırayla veri almak istiyorum.

Girişim JOIN:

SELECT I.* FROM items AS I 
JOIN some_chosen_data_in_order AS S ON I.id = ANY(S.id_items) WHERE S.id = ? 

İkinci girişim şu şekilde oldu:

SELECT I.* FROM items AS I 
WHERE I.id = ANY 
(ARRAY[SELECT S.id_items FROM some_chosen_data_in_order WHERE id = ?]) 

Ancak bunların hiçbiri, kimlikleri dizi alanında olduğu gibi aynı sırada tutmuyor. Xzx44 tablosundan, belirli bir satır için some_chosen_data_in_order tablosundan dizi kimlikleriyle eşleşen veriye nasıl yardımcı olabilirsiniz?

cevap

43
SELECT t.* 
FROM unnest(ARRAY[1,2,3,2,3,5]) item_id 
LEFT JOIN items t on t.id=item_id 

Yukarıdaki sorgu öğeleri seçin: bu sırayla 1,2,3,2,3,5. Demek istediğin bu mu? :)

+0

unnest() gerçekten harika bir oyun! Bir müşterinin ID'lerinin bir listesi vardı ve onlara karşı katılmaları gerekiyordu, ancak bir geçici masala yapmanın bir yolunu bulmak istedim. Katılabilirsiniz (dürüst olarak (ARRAY [1,2,3])) idlist olarak seçilebilir ve bir şampiyon gibi çalışır. Teşekkürler! – apinstein

+0

@apinstein bana sorguyu gösterebilir misin? hala dint olsun –

+1

Mükemmel ipucu, teşekkürler – Valentin

23

Masanızın muhtemelen normalleştirilmesi size verebileceğim en iyi tavsiyedir.

Int_array contrib module, dizideki int dizin konumunu verecek bir idx işlevine sahiptir. Ayrıca, snippets wiki üzerinde herhangi bir veri türünün dizileri için çalışan bir idx işlevi vardır. kimlikli items tablodan

SELECT i.*, idx(id_items, i.id) AS idx 
FROM some_chosen_data_in_order s 
JOIN items i ON i.id = ANY(s.id_items) 
ORDER BY idx(id_items, i.id) 
+1

Bu tam olarak neye ihtiyacım var. Thanx! Veritabanımı verimlilik nedenleriyle denormal yapıyorum. – Adiasz

0
SELECT I.* FROM items AS I 
WHERE I.id IN (SELECT UNNEST(id_items) FROM some_chosen_data_in_order 
(ARRAY[SELECT S.id_items FROM some_chosen_data_in_order WHERE id = ?]) 
+1

Kodu kod olarak eklerken, gelecekteki okuyucular için cevabınıza biraz açıklama ekleyin. – HaveNoDisplayName