• 19-07-2017, 18:51:49
    #10
    MuratOSMA adlı üyeden alıntı: mesajı görüntüle
    Pek anlamam ama.. category_id'sini c.id IN(4,5,6,83,84) yapmak ile (c.id=5 OR c.id=6) AND c.id=4 AND (c.id=83 OR c.id=83) arasındaki fark nedir?
    IN(4,5,6,83,84); arama yapılan sütun 4,5,6,83 veya 84 olan tüm satırları döndürür.

    diğeri ise ilgili sütunda 5 veya 6 değeri taşıyan aynı zamanda ilgili sütunda 4 de bulunan aynı zamanda yine ilgili sütunlarda 83 veya 84 değeri taşıyan satırları döndürür.. tabi istediğim sonucu anlatabilmek adına yazdığım sorguda tüm kriterler cat_id sütununda aranmıştır ve bir satırın bir sütununda sadece bir değer olabileceği için mantıksız bi sorgudur. Sadece istediğim sonucu anlatabilmek adına yazdım.
  • 19-07-2017, 19:16:53
    #11
    Daha önceki mesajlarda yazıldığı üzre öncelikle product tablosu ile category tablosunu ilişkilendirmek için üçüncü bir tabloya ihtiyaç var. Buna product_category diyelim.

    Aşağıdaki resimde örnek olarak tabloyu bir kaç girişle doldurdum.



    Resimden de görüleceği üzere bir ürün birden fazla kategoriye eklenmiş durumda. product_category tablosu inner join ile product tablosuna bağlanacak.

    SELECT product_category.product_id from (
    (select * from product_category where product_category.category_id=5 or product_category.category_id=6
    union
    select * from product_category where product_category.category_id=83 or product_category.category_id=84)
    ) AS product_category 
    inner join product on product.product_id=product_category.product_id
    where product_category.product_id in(select product_category.product_id from product_category where product_category.category_id=4)
    GROUP BY product_category.product_id HAVING count(*) >= 2;
    Sorgu Açıklaması:
    Öncelikle or içeren iki sorguyu union ile birleştiriyoruz.
    Elde ettiğimiz sonucu inner join ile product tablosuna bağlıyoruz.
    Daha sonra tekli sorguyu da ilave ediyoruz.
    Sonunda da birden fazla sonuç dönmemesi için grupluyoruz.

    Bu istenileni karşılıyor . 1 ve 5 id li ürünleri döndürüyor. Fakat sorgu ne kadar efektif ve performans gösterir mi bilemiyorum. Belki farklı bir mantıkla daha iyi olur. Onu da ustalara bırakalım
  • 19-07-2017, 19:26:57
    #12
    selcukhoca adlı üyeden alıntı: mesajı görüntüle
    Daha önceki mesajlarda yazıldığı üzre öncelikle product tablosu ile category tablosunu ilişkilendirmek için üçüncü bir tabloya ihtiyaç var. Buna product_category diyelim.

    Aşağıdaki resimde örnek olarak tabloyu bir kaç girişle doldurdum.



    Resimden de görüleceği üzere bir ürün birden fazla kategoriye eklenmiş durumda. product_category tablosu inner join ile product tablosuna bağlanacak.

    SELECT product_category.product_id from (
    (select * from product_category where product_category.category_id=5 or product_category.category_id=6
    union
    select * from product_category where product_category.category_id=83 or product_category.category_id=84)
    ) AS product_category 
    inner join product on product.product_id=product_category.product_id
    where product_category.product_id in(select product_category.product_id from product_category where product_category.category_id=4)
    GROUP BY product_category.product_id HAVING count(*) >= 2;
    Sorgu Açıklaması:
    Öncelikle or içeren iki sorguyu union ile birleştiriyoruz.
    Elde ettiğimiz sonucu inner join ile product tablosuna bağlıyoruz.
    Daha sonra tekli sorguyu da ilave ediyoruz.
    Sonunda da birden fazla sonuç dönmemesi için grupluyoruz.

    Bu istenileni karşılıyor . 1 ve 5 id li ürünleri döndürüyor. Fakat sorgu ne kadar efektif ve performans gösterir mi bilemiyorum. Belki farklı bir mantıkla daha iyi olur. Onu da ustalara bırakalım
    Hocam teşekkürler, içiçe sorguları pek kullanmıyorum dolayısıyla bi bakışta mantığı anlamadım, ben de store_product_extend_cat adlı bi kesişim tablosuyla aşağıdaki şekilde sonuca ulaştım (sanırım) bikaç saniye önce ama filtreye elkencek kategori_id'si adedince inner join eklemem gerekiyor sanırım filtreleme sayısına kısıtlama getirmem gerekçek.

    SELECT c1.* FROM store_product_extend_cat as c1
    INNER JOIN store_product_extend_cat AS c2
    ON c1.product_id=c2.product_id
    INNER JOIN store_product_extend_cat AS c3
    ON c1.product_id=c3.product_id
    WHERE (c1.cat_id=75 AND c2.cat_id=76) OR (c3.cat_id=73 )
    GROUP BY c1.product_id

    Sizinkini de inceleyip araştırıyorum hocam performans için neler diyolar bakalım. Daha iyi bi çözüm önerisi gelmezse ikisi arasında bi seçim yapçam ilginiz için çok çok teşekkürler. R10+

    Muhtemelen performans açısından sizin sorgunuz daha başarılı. Borçlandım hocam sana gün gelir ben de yardım edebilirim umarım. İyi çalışmalar.
  • 19-07-2017, 20:13:18
    #13
    codeksper adlı üyeden alıntı: mesajı görüntüle
    Hocam teşekkürler, içiçe sorguları pek kullanmıyorum dolayısıyla bi bakışta mantığı anlamadım, ben de store_product_extend_cat adlı bi kesişim tablosuyla aşağıdaki şekilde sonuca ulaştım (sanırım) bikaç saniye önce ama filtreye elkencek kategori_id'si adedince inner join eklemem gerekiyor sanırım filtreleme sayısına kısıtlama getirmem gerekçek.

    SELECT c1.* FROM store_product_extend_cat as c1
    INNER JOIN store_product_extend_cat AS c2
    ON c1.product_id=c2.product_id
    INNER JOIN store_product_extend_cat AS c3
    ON c1.product_id=c3.product_id
    WHERE (c1.cat_id=75 AND c2.cat_id=76) OR (c3.cat_id=73 )
    GROUP BY c1.product_id

    Sizinkini de inceleyip araştırıyorum hocam performans için neler diyolar bakalım. Daha iyi bi çözüm önerisi gelmezse ikisi arasında bi seçim yapçam ilginiz için çok çok teşekkürler. R10+

    Muhtemelen performans açısından sizin sorgunuz daha başarılı. Borçlandım hocam sana gün gelir ben de yardım edebilirim umarım. İyi çalışmalar.
    Yukarıda ki sorguya dikkat etmemiştim o kadar uzatmanıza gerek yok hocam konu içerisinde ki arkadaşların izlediği yöntem doğru ancak yol uzun.

    Product tablosuna bir alan daha açın category_id olsun kategori eşleştirme için ;
    Ürün Tablosu : 
    id | category_id (varchar) | name
    1  | 2,1		 | Ürün Adı
    2  | 1,11		 | Genel Kategorisine Eklenen Ürün Adı.
    // Tekrar düzenlendi.
    // Örnek Sorgu ;
    SELECT * FROM products WHERE 
    FIND_IN_SET( 1 , category_id )
    OR FIND_IN_SET( 2 , category_id )
    ALTERNATİF ve ESNEK YÖNTEM

    İlişkilendirme için relationships adında bir tablo açarsınız örnek yapısını iletiyorum

    relationships ; 
    object_id ( hangi ürün ilişkilendiriliyor ) | action_id ( ilişkilendirilen kategori id ) | type ( tür esnek kullanım için eklenebilir )
    1											| 1									| category
    2											| 2									| category
    Örnek Sorgu ;
    SELECT * FROM products WHERE id IN ( SELECT object_id FROM relationships WHERE action_id IN( 1 , 2 , 3, 4 )  AND type = 'category' )
    //
    // Alternatif
    SELECT
    	products.*
    FROM
    	products 
    LEFT JOIN 
    	relationships
    ON
    	relationships.object_id= products.id
    WHERE
    	relationships.action_id IN ( 1, 2 )
    		AND
    	relationships.type = 'category'
    // Alternatif
    SELECT * FROM products WHERE id IN 
    ( 
    	SELECT 
    		object_id 
    	FROM 
    		relationships 
    	WHERE 
    		action_id IN(1,2) 
    		veya 
    		action_id = 2
    )
    Bir kaç açıklama ekleyeyim ;

    relationships tablosunda ki type alanını neden ekledim ?
    Varsayalım bir galeri modülünüz var ve bunda da kategorilerinizi eşleştirmek ve kullanmak istiyorsunuz.
    type alanı olduğu için tür belirterek galeri kategori eşleştirmesini tamamlayabilirsiniz eğer type alanı olmasaydı object_id'ye eklenen ürün id ile galeri'nin id'sinin çakışma olasılığı mevcuttu " AND type = 'gallery' " veya " AND type = 'category' " diyerek bundan kaçınabiliyoruz ve böylelikle sizde birden fazla tablo açmamış oluyorsunuz tek tablo üzerinden tüm eşleşmelerinizi yapabiliyorsunuz.

    Performans olayına gelirsek :
    IN içerisinde (SUBQUERY) select attığım için 2 sorgu sormakta
    Gözle görülür bir fark yaşamazsınız ancak join subquery'den daha hızlı çalışır.

    Tavsiyem ise ilk söylediğim yöntemi kullanmanız ( FIND_IN_SET ).