получить значения с изначально одним неизвестным

Тема в разделе "Базы данных", создана пользователем sol_los, 24 май 2015.

Модераторы: latteo
  1. sol_los

    sol_los

    Регистр.:
    17 окт 2011
    Сообщения:
    294
    Симпатии:
    118
    возможно не могу верно сформулировать оттого у самого и не получается сделать выборку
    имеется таблица
    id_feature id_product id_feature_value
    12 14500 135
    13 14500 185
    14 14500 107
    15 14500 180
    16 14500 360
    в ней множество таких продуктов
    необходимо получить id_product с такими же id_feature и id_feature_value как у 14500 но не все,а только те id_feature которых мы задаем.

    на php изначально набросал вот так, как бы это все дело сократить?


    PHP:
     $idFeature1 12;
            
    $idFeature2 13;
            
    $idFeature3 11;
           
            
    $productId 14500;
           
            
    $idValueFeature1 Db::getInstance()->executeS('SELECT `id_feature_value` FROM `'._DB_PREFIX_.'feature_product` WHERE  `id_product` = '.$productId.'  AND `id_feature` = '.$idFeature1.'');
            
    $idValueFeature2 Db::getInstance()->executeS('SELECT `id_feature_value` FROM `'._DB_PREFIX_.'feature_product` WHERE  `id_product` = '.$productId.'  AND `id_feature` = '.$idFeature2.'');
            
    $idValueFeature3 Db::getInstance()->executeS('SELECT `id_feature_value` FROM `'._DB_PREFIX_.'feature_product` WHERE  `id_product` = '.$productId.'  AND `id_feature` = '.$idFeature3.'');
          
            
    $idSimilarProduct Db::getInstance()->executeS('SELECT DISTINCT `id_product` FROM `'._DB_PREFIX_.'feature_product`          
                        WHERE
                    `id_feature_value` IN ('
    .$idValueFeature1[0]["id_feature_value"].', '.$idValueFeature2[0]["id_feature_value"].', '.$idValueFeature3[0]["id_feature_value"].') AND `id_feature` IN ('.$idFeature1.', '.$idFeature2.', '.$idFeature3.')
                    '
    );
     
  2. nejtr0n

    nejtr0n Постоялец

    Регистр.:
    24 янв 2014
    Сообщения:
    124
    Симпатии:
    67
    По-моему, если я правильно понял задачу (Опишите конкретней логику запроса), можно использовать запрос вида:
    Код:
    select id_product from test123 where id_feature_value in (select id_feature_value from test123 where id_product=14500 and id_feature in (12,13));
     
    sol_los нравится это.
  3. sol_los

    sol_los

    Регистр.:
    17 окт 2011
    Сообщения:
    294
    Симпатии:
    118
    спасибо, то что нужно, но получаю ошибку
    глаза проглядел, не вижу где косяк
    You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 5
    Код:
    SELECT DISTINCT fp.`id_product` FROM `ps_feature_product` fp
                        INNER JOIN `ps_stock_available` s ON fp.`id_product` = s.`id_product` AND s.`quantity` >0
                            WHERE `id_feature_value` IN (SELECT fv.`id_feature_value` FROM `ps_feature_product` fv
                            WHERE fv.`id_product` = 14415
                     AND fv.`id_feature` IN (12, 13, 11)
    логика запроса:
    получить ид всех продуктов у которых ид свойства (которые мы задаем) и ид значения конкретного товара совпадают
     
  4. nejtr0n

    nejtr0n Постоялец

    Регистр.:
    24 янв 2014
    Сообщения:
    124
    Симпатии:
    67
    В приведённом выше примере нет закрывающей скобки
     
    sol_los нравится это.
  5. latteo

    latteo Эффективное использование PHP, MySQL

    Moderator
    Регистр.:
    28 фев 2008
    Сообщения:
    1.547
    Симпатии:
    1.419
    кажется всего лишь потерял закрывающую скобку ;)

    WHERE `field` IN (подзапрос) - может быть крайне тормознутым...
    лучше попробуй на джойнах, джойня таблицу саму на себя по `id_feature_value` и `id_feature`
     
    sol_los нравится это.
  6. sol_los

    sol_los

    Регистр.:
    17 окт 2011
    Сообщения:
    294
    Симпатии:
    118
    что-то не догоняю как это вернее сделать что бы снова не использовать IN
    да еще нужно улучшить предыдущий запрос, т.к. получается происходит выборка по условию
    id_feature - возвращает [id_product]
    id_feature_value - возвращает [id_product]
    и получаю уникальные id_product

    а нужно что бы совпадение id_feature и id_feature_value у id_product возвращало [id_product]
     
  7. nejtr0n

    nejtr0n Постоялец

    Регистр.:
    24 янв 2014
    Сообщения:
    124
    Симпатии:
    67
    К сожалению, ничего не понятно о задаче.
    Вот Ваш запрос без использования IN
    Код:
    select distinct t2.id_product from
    test123 as t1 inner join
    test123 as t2 on t2.id_feature_value=t1.id_feature_value
    where t1.id_product=14500
    and t1.id_feature=12
    or t1.id_feature=13
    or t1.id_feature=14;
    
     
    sol_los и latteo нравится это.
  8. sol_los

    sol_los

    Регистр.:
    17 окт 2011
    Сообщения:
    294
    Симпатии:
    118
    попробую еще разъяснить на примере.

    допустим в магазине есть товар, у этого товара имеются свойства, такие как размер, цвет, ткань, страна производитель
    у свойств есть значение - ткань: шерсть, цвет:синий, страна производитель: македония

    основной смысл вывести товары идентичные по значениям свойств, но не по всем, а например по размеру и ткани

    привязка свойства и его параметра в базе происходит так:
    свойство = id_feature
    значение свойства = id_feature_value
    ид товара = id_product
    Код:
    id_feature   id_product   id_feature_value
    12             14500         135
    13             14500         185
    14             14500         107
    12             14110         135
    13             14110         185 
    14             14110         107
     
    допустим нас интересует только: размер - id_feature = 13 и ткань - id_feature = 14, производитель и цвет нам не нужен.

    на страницу товара при загрузке передается ид товара и ид свойства, ид значения я не знаю
    поэтому в самом первом варианте, в старпосте, я получал из базы по ид продукта(id_product) и ид свойства(id_feature) - ид значения свойства(id_feature_value)
    а уже после выбирал ид товаров к которым были привязаны те же ид свойства(id_feature) и уже полученный ид значения свойства(id_feature_value)

    т.е. мне нужны ид товара у которых
    id_feature = 13 и id_feature_value = 185,
    а так же
    id_feature = 14 и id_feature_value = 107

    в общем если совсем по бестолковому то можно вот так

    PHP:
            $idFeature1 12;
            
    $idFeature2 13;
            
    $idFeature3 11;       

            
    $productId Tools::getValue('id_product');
          
          
            
    $idValueFeature1 Db::getInstance()->executeS('SELECT `id_feature_value` FROM `'._DB_PREFIX_.'feature_product` WHERE  `id_product` = '.$productId.'  AND `id_feature` = '.$idFeature1.'');
            
    $idValueFeature2 Db::getInstance()->executeS('SELECT `id_feature_value` FROM `'._DB_PREFIX_.'feature_product` WHERE  `id_product` = '.$productId.'  AND `id_feature` = '.$idFeature2.'');
            
    $idValueFeature3 Db::getInstance()->executeS('SELECT `id_feature_value` FROM `'._DB_PREFIX_.'feature_product` WHERE  `id_product` = '.$productId.'  AND `id_feature` = '.$idFeature3.'');
        
            
    $idSimilarProduct1 Db::getInstance()->executeS('SELECT DISTINCT fp.`id_product` FROM `'._DB_PREFIX_.'feature_product` fp
                        INNER JOIN `' 
    _DB_PREFIX_ 'stock_available` sa ON fp.`id_product` = sa.`id_product` AND sa.`quantity` >0
                        WHERE `id_feature_value` = '
    .$idValueFeature1[0]["id_feature_value"].' AND `id_feature` = '.$idFeature1.'');
          
            
    $idSimilarProduct2 Db::getInstance()->executeS('SELECT DISTINCT fp.`id_product` FROM `'._DB_PREFIX_.'feature_product` fp
                        INNER JOIN `' 
    _DB_PREFIX_ 'stock_available` sa ON fp.`id_product` = sa.`id_product` AND sa.`quantity` >0
                        WHERE fp.`id_feature_value` = '
    .$idValueFeature2[0]["id_feature_value"].' AND `id_feature` = '.$idFeature2.'');
             
    $idSimilarProduct3 Db::getInstance()->executeS('SELECT DISTINCT fp.`id_product` FROM `'._DB_PREFIX_.'feature_product` fp
                        INNER JOIN `' 
    _DB_PREFIX_ 'stock_available` sa ON fp.`id_product` = sa.`id_product` AND sa.`quantity` >0
                        WHERE fp.`id_feature_value` = '
    .$idValueFeature3[0]["id_feature_value"].' AND `id_feature` = '.$idFeature3.'');

    получившиеся массивы сравнить и вернуть уникальные id_product
     
    Последнее редактирование модератором: 21 фев 2016
  9. nejtr0n

    nejtr0n Постоялец

    Регистр.:
    24 янв 2014
    Сообщения:
    124
    Симпатии:
    67
    Если поле id_feature_value не известно, тогда таким запросом
     
    sol_los нравится это.
  10. sol_los

    sol_los

    Регистр.:
    17 окт 2011
    Сообщения:
    294
    Симпатии:
    118
    таким получилось по времени выполнения 25 сек и 9000 позиций в ответе.

    Код:
    SELECT DISTINCT fp2.`id_product` FROM `ps_feature_product` AS fp2                   
                        INNER JOIN `ps_feature_product` AS fp1 ON fp2.`id_feature_value` = fp1.`id_feature_value`
                        WHERE  fp1.`id_product` = 14415
                        AND fp1.`id_feature` = 12 OR fp1.`id_feature` = 13 OR fp1.`id_feature` = 11
    предыдущий запрос с AND IN, отработал за 0,25 и вернул 3000 результатов.

    где-то я туплю?
     
    Последнее редактирование: 25 май 2015