çocukları seçmek için mySQL sorgu

7 Cevap php

Bu mySQL mümkün olup olmadığından emin değilim. İşte benim tablolar şunlardır: -

Categories table - id - name - parent_id (which points to Categories.id)

Ben tüm kategoriler ve alt kategoriler haritasına yukarıdaki tabloyu kullanın.

Products table - id - name - category_id

, Ait olduğu alt kategori id Ürünler tablosu puan category_id.

örneğin Ben ABC ürün Oyuncaklar> Eğitim> ABC varsa, Oyuncak Kategori ve Eğitim daha sonra ABC 2 olarak category_id olacak, alt kategorisi olduğunu.

Şimdi sorun, ben belirli bir kategori için (tüm alt kategoriler ve bunların alt kategorilerinde .. n seviye) tüm ürünlerini görüntülemek için bir SQL sorgusu kullanmak istiyor.

örneğin category.name = 'Oyuncak' ve kategoriler, ürünler .... * seçin

Yukarıdaki sorgu da Eğitim gelen ürünleri ve tüm diğer alt kategoriler ve bunların alt göstermelidir.

Bu mySQL sorgu kullanarak mümkün mü? Değilse ne gibi seçenekler var? Ben PHP özyineleme önlemek istiyorum.

Update: Temelde ürünleri masaya vurur bir sütun ekleyerek yapıyorum edilecek ana kategorisinde ilk 10 ürünleri görüntülemek istiyorum.

Teşekkür ederim

7 Cevap

Ben aynı şeyi yapmak için gerekli ettik önceki projelerinde ne yaptık, iki yeni sütunlar ekledik.

  • i_depth: kategori ne kadar derin int değeri
  • nvc_breadcrumb: biçimi bir kırıntı türü kategori tam yol

Ve sonra (her üç güncellemeler aynı tetikleyici olan) aşağıdakileri yapmak için kategori bilgi evleri tabloya bir tetikleyici eklendi ...

-- Reset all branches
UPDATE t_org_branches
	SET nvc_breadcrumb = NULL,
	i_depth = NULL

-- Update the root branches first
UPDATE t_org_branches 
	SET nvc_breadcrumb = '/', 
		i_depth = 0 
	WHERE guid_branch_parent_id IS NULL

-- Update the child branches on a loop
WHILE EXISTS (SELECT * FROM t_branches WHERE i_depth IS NULL) 
	UPDATE tobA 
		SET tobA.i_depth = tobB.i_depth + 1, 
			tobA.nvc_breadcrumb = tobB.nvc_breadcrumb + Ltrim(tobA.guid_branch_parent_id) + '/' 
		FROM t_org_branches AS tobA
			INNER JOIN t_org_branches AS tobB ON (tobA.guid_branch_parent_id = tobB.guid_branch_id) 
		WHERE tobB.i_depth >= 0 
			AND tobB.nvc_breadcrumb IS NOT NULL 
			AND tobA.i_depth IS NULL

Ve sonra sadece bir kategori kimliği üzerinde ürünler tablo ile katılmak ve bir "LIKE '% / [categoryID] /%'" yaparsınız. Bu MS SQL yapıldığını unutmayın, ama bir MySQL sürümüne çevirmek için yeterli kolay olmalıdır.

Bu sadece (tablo ve sütun isim değişikliği sonrası) bir kesim ve yapıştırma için yeterince uyumlu olabilir.


Açıklama genişletilmesi ...

t_categories (şimdi haliyle) ...

Cat Parent	CategoryName
1   NULL	MyStore
2   1		Electronics
3   1		Clothing
4   1		Books
5   2		Televisions
6   2		Stereos
7   5		Plasma
8   5		LCD

(değiştikten sonra) t_categories ...

Cat  Parent  CategoryName   Depth	Breadcrumb
1   NULL	MyStore			NULL	NULL	
2   1		Electronics		NULL	NULL
3   1		Clothing		NULL	NULL
4   1		Books			NULL	NULL
5   2		Televisions		NULL	NULL
6   2		Stereos			NULL	NULL
7   5		Plasma			NULL	NULL
8   5		LCD				NULL	NULL

t_categories (script kullanımdan sonra verdim)

Cat  Parent  CategoryName   Depth	Breadcrumb
1   NULL	MyStore			0		/	
2   1		Electronics		1		/1/
3   1		Clothing		1		/1/
4   1		Books			1		/1/
5   2		Televisions		2		/1/2/
6   2		Stereos			2		/1/2/
7   5		LCD				3		/1/2/5/
8   7		Samsung			4		/1/2/5/7/

t_products (Eğer şimdi olduğu gibi, hiçbir değişiklik) ...

ID   Cat Name
1   8	Samsung LNT5271F
2   7	LCD TV mount, up to 36"
3   7	LCD TV mount, up to 52"
4   5	HDMI Cable, 6ft

Kategoriler ve ürünler Üyelik (kategori C, ürün P)

C.Cat Parent CategoryName   Depth	Breadcrumb	ID	 p.Cat	Name
1    NULL	MyStore			0		/			NULL NULL	NULL
2    1		Electronics		1		/1/			NULL NULL	NULL
3    1		Clothing		1		/1/			NULL NULL	NULL
4    1		Books			1		/1/			NULL NULL	NULL
5    2		Televisions		2		/1/2/		4	 5		HDMI Cable, 6ft
6    2		Stereos			2		/1/2/		NULL NULL	NULL
7    5		LCD				3		/1/2/5/		2	 7		LCD TV mount, up to 36"
7    5		LCD				3		/1/2/5/		3	 7		LCD TV mount, up to 52"
8    7		Samsung			4		/1/2/5/7/	1	 8		Samsung LNT5271F

Şimdi her kategori ve hiçbir boş değerlere de şeyler var, böylece ürünlerin tablo daha tam olduğunu varsayarak, ben sağlanan son tablosunun son üç ürün almak için bir "Kırıntı LIKE '% / 5 /%'" yapabilirdi. O (Samsung tv gibi) kategorinin doğrudan öğeleri ve çocuklar var dikkat edin. Sadece bir "c.cat = 5" do SADECE özel kategori öğeleri istiyorum.

Bunu başarmak için en temiz yol nested set model kullanmak olacağını düşünüyorum. Bu biraz uygulamak için karmaşık, ama kullanmak için güçlü. MySQL adında bir öğretici vardır Managing Hierarchical Data in MySQL. Joe Celko aynı şey hakkında yazdığı büyük SQL uzmanları biri here. Hatta daha fazla bilgiye ihtiyacınız varsa Troel's links on storing hierarchical data bakabilirsiniz.

Benim durumumda uzağa veri bu tür depolamak ve bu durumda veri aslında bir yönlendirilmiş grafik olarak, bunun yerine bir grafik veritabanını kullanmak için bir RDBMS'yi kullanarak kalacaktı.

Her grup için tam bir virgülle ayrılmış ağacı içerecek Kategoriler tabloya bir sütun ekleyin. Sizin örnek kullanarak, alt-kategori Eğitim ağaç '1, 2 ', olarak bu olurdu burada 1 = Oyuncaklar, 2 = Eğitim (kendisini içerir). Kategorilerin sonraki iç içe düzey ağaca eklemeye devam ediyorum.

Bir gruptaki tüm ürünleri almak için, bunu gibi, MySQL FIND_IN_SET işlevini kullanın

SELECT p.ID 
FROM Products p INNER JOIN Categories c ON p.category_ID = c.ID
WHERE FIND_IN_SET(your_category_id, c.tree)

Ben bu sorgu bir dizin kullanabilirsiniz sanmıyorum ben, büyük tablolar için bu yöntemi kullanmak olmaz.

Bir yolu soyundan ilişkiler atası içeren bir tablo korumaktır. Bu özel tablo sorgulamak ve tüm bakmakla yükümlü listesini alabilirsiniz.

MySQL varsayarsak, PHP özyineleme önlemek için zor olacak.

Sizin soru MySQL Oracle'ın CONNECT BY PRIOR sözdizimi nasıl taklit, aslında,. İnsanlar bu sormak question repeatedly fakat MySQL için yapılmış asla ve uygulanması saklı prosedürler yoluyla muhtemelen işe yaramayacak bir özellik (şimdi) stored functions cannot be recursive çünkü .

Şimdiye kadar sunulan veritabanı kludges sakının.

Iyi bilgi çok uzak three links from nawroth:

Masa Kategori ne kadar büyük? Sen uygulama düzeyinde bu önbelleğe ve uygun sorgu oluşturmak gerekebilir: ... nerede id (2, 3, 6, 7)

Eğer endeksli ve adına göre bulma aksine hızlı olarak, kendilerine özgü bir kimliktir id kategorileri getirme eğer Ayrıca, bu en iyisidir.

Ben böyle bir şey yapmadım çünkü, benimle çıplak.

BEGIN
  SET cat = "5";
  SET temp = "";

  WHILE STRCMP(temp, cat) != 0 DO
    SET temp = cat;
    SET cat = SELECT CONCAT_WS(GROUP_CONCAT(id), cat) FROM Categories GROUP BY (parent_id) HAVING FIND_IN_SET(parent_id, cat);
  END LOOP;
END;

SELECT * FROM products WHERE FIND_IN_SET(category_id, cat)

Neredeyse üzerinde çalışmaz garanti edemez, ama ben yapmaya çalışıyorum görebilirsiniz. Ben bu kadar var ve ben sadece üzgünüm, (her kategoriden üst N seçin) sorgunun sonuna bitirmek için karar verdi. : P