• 04-08-2020, 17:05:12
    #1
    Merhaba arkadaşlar,

    Bir proje de detaylı bir filtreleme yapmam gerekiyor. Takıldığım bir nokta var, önerileriniz olursa çok sevinirim.

    İçerik tablosu:
    id | title | options | value
    -----------------------------
    1 | x içerik | 1,2,3 | 100
    -----------------------------
    2 | y içerik | 3,2,4,| 123
    -----------------------------
    3 | z içerik | ,5,7,9| 287
    Kullanıcının checkbox tipi input ile seçim yapmasını sağlayarak elde ettiğim dizi var.
    Örneğin kullanıcıdan gelen veri:
    $get = [
        'value' => [
            'min' => 29
            'max' => 80
        ],
        'options' => [
            0 => 3
            1 => 4
            2 => 1
        ],
    ];
    Şuanda kullanıcıdan gelen veriyi LIKE ile veritabanında sorgulatıyorum.

    SELECT * FROM contents WHERE (options LIKE "%3%" OR options LIKE "%4" OR options LIKE "%1%") AND (value => 29 AND value <= 80)
    Fakat bu sorgu çok sağlıklı çalışmamakta.
    Problemin kaynağında virgül ile ayırdığım options sütunundaki verileri LIKE ile seçmemden kaynaklandığını düşünüyorum.
    Örneğin kullanıcının seçimi doğrultusunda options gelen "3" değerini tabloda LIKE ile seçmek istediğim de "35" veya "93" değerlerini de seçmiş oluyor.
    Tabloyu yapısını da şuan düzenleme şansım olmadığından dolayı ciddi sorun yaşamaktayım.

    Bu konuda önerisi olan var mıdır?
  • 04-08-2020, 17:28:20
    #2
    denediniz mi bilmiyorum ama like kısmında "%3%" yerine "%3" şeklinde kullanırsanız tüm değişkenler için için belki işe yarayabilir.
  • 04-08-2020, 17:30:51
    #3
    Verilerin virgül ile ayrılarak veritabanında saklanması doğru bir kullanım değil. JSON olarak saklayabilirsiniz. Değiştirme şansınız olmadığı için CONCAT LIKE anahtar kelimeleri ile bir araştırma yapabilirsiniz. Emin olmamakla birlikte bu yöntemin sizin işinize yarayacağını düşünüyorum.
  • 04-08-2020, 17:31:12
    #4
    SELECT * FROM contents WHERE (options in (2,3)) and (value between 29 and 80)

    Bu daha iyi olacaktır
  • 04-08-2020, 18:21:50
    #5
    beatrax adlı üyeden alıntı: mesajı görüntüle
    ilk hatan,

    AND (value => 29 AND value <= 80) yerine;

    AND (value BETWEEN 29 AND 80)

    ikincisi bi kere option'ları bu tabloda tutman doğru olmamış ama değiştiremiyosan hepsi virgül içerdiği için başında ve sonunda;

    options LIKE '%,3,%' şeklinde çözebilirsin.
    Aslında BETWEEN kullanıyorum, "(value => 29 AND value <= 80)" ifadesi bir örnekti. Sorgunun devamı olacağını göstermek için eklemiştim ama dikkatsizce örnek vermişim.
    Tablo yapısının yanlış olduğunun farkındayım fakat tabloyu maalesef ben kurgulamadım ve değiştirme şansım da yok. Bahsettiğin gibi ('%,3,%') kullanabilmem için tüm ayraçlar virgül ile başlayıp virgül ile bitmeli.
    Ama PHP tarafında explode ve implode kullandığım için bu koşul her zaman geçerli olmuyor. Daha pratik bir yoluna bakıyorum, bulamazsam son çare olarak bunu değerlendireceğim. Teşekkür ederim

    hyPerdarKness adlı üyeden alıntı: mesajı görüntüle
    denediniz mi bilmiyorum ama like kısmında "%3%" yerine "%3" şeklinde kullanırsanız tüm değişkenler için için belki işe yarayabilir.
    Bir üst yorum da da ifade ettiğim gibi bunu son seçenek olarak değerlendiriyorum. Nedense uzak durmam gereken bir çözüm gibi geliyor. Teşekkür ederim

    tematem adlı üyeden alıntı: mesajı görüntüle
    Verilerin virgül ile ayrılarak veritabanında saklanması doğru bir kullanım değil. JSON olarak saklayabilirsiniz. Değiştirme şansınız olmadığı için CONCAT LIKE anahtar kelimeleri ile bir araştırma yapabilirsiniz. Emin olmamakla birlikte bu yöntemin sizin işinize yarayacağını düşünüyorum.
    MYSQL tarafım çok güçlü değil Concat Like konusunu araştıracağım. Teşekkür ederim

    ahmethekim14 adlı üyeden alıntı: mesajı görüntüle
    SELECT * FROM contents WHERE (options in (2,3)) and (value between 29 and 80)

    Bu daha iyi olacaktır
    options in (2,3) şeklinde kullanabilmem için options sütunu INT olması gerekmez mi? Şuanda virgüllerden dolayı benim options sütunum VARCHAR. Bu konuda bilgilendirebilir misiniz?
  • 04-08-2020, 18:29:41
    #6
    where FIND_IN_SET( 3, options ) order by id desc
    @ahmetsmc; Eğer kolon içerisinde bulunan text'i virgül ile bölümlüyorsan find_in_set fonksiyonuyla içerisinde arama yapabilirsin, like'a göre daha hızlıdır ve %100 doğru sonucu alırsın.
  • 04-08-2020, 19:44:10
    #7
    wave adlı üyeden alıntı: mesajı görüntüle
    where FIND_IN_SET( 3, options ) order by id desc
    @ahmetsmc; Eğer kolon içerisinde bulunan text'i virgül ile bölümlüyorsan find_in_set fonksiyonuyla içerisinde arama yapabilirsin, like'a göre daha hızlıdır ve %100 doğru sonucu alırsın.
    Teşekkürler sanırım aradığımı buldum. Bir kaç deneme yaptım şuan için bir soruna rastlamadım.
    FIND_IN_SET( '3,2,1', options ) şeklinde de kullanılabiliyor anladığım kadarıyla.
  • 04-08-2020, 21:10:32
    #8
    wave adlı üyeden alıntı: mesajı görüntüle
    where FIND_IN_SET( 3, options ) order by id desc
    @ahmetsmc; Eğer kolon içerisinde bulunan text'i virgül ile bölümlüyorsan find_in_set fonksiyonuyla içerisinde arama yapabilirsin, like'a göre daha hızlıdır ve %100 doğru sonucu alırsın.
    tek sütunda virgüllü veri aramasında bu kod parçacığı hayat kurtarıyor benimde bütün yükümü almıştı üzerimden. Siz yazmamış olsaydınız ben yazacaktım.
  • 05-08-2020, 09:26:36
    #9
    ahmetsmc adlı üyeden alıntı: mesajı görüntüle
    Teşekkürler sanırım aradığımı buldum. Bir kaç deneme yaptım şuan için bir soruna rastlamadım.
    FIND_IN_SET( '3,2,1', options ) şeklinde de kullanılabiliyor anladığım kadarıyla.
    Denemeden ziyade, fonksiyonu incelemeni öneririm. Fonksiyonun ilk parametresi string'dir ve iğne'yi temsil eder, ikinci parametreside string'dir ve samanlığı temsil eder. Dolayısıyla ikinci parametre içinde verdiğin ilk parametreyi arar. İlk parametre olarak verdiğin "3,2,1" 'i bütün olarak arayacaktır yani eğer options kolonun da 4,3,6,2,1 gibi bir değer varsa bunu bulamaz.
    Bu fonksiyonun multiple özelliği yok eğer olsaydı zaten ilk parametrede alternatif olarak array'de kabul ederdi, dolayısıyla 3 2 ve 1'i "OR WHERE" şeklinde araman gerekir.