Jump to content
  • 0

Отбор элементов по нескольким параметрам


user
 Share

Question

SELECT DISTINCT(virtuemart_product_id) FROM #__virtuemart_product_customfieldsWHERE virtuemart_product_id IN(SELECT DISTINCT(virtuemart_product_id)FROM #__virtuemart_product_customfields WHERE custom_value='ACURA' and virtuemart_custom_id=4)AND custom_value='1997' and virtuemart_custom_id=3

e7f4354bdb333797ca62d161e4f11061.jpg

Помогите с такой задачей.Запрос отбирает элементы по двум параметрам.В данном случае это будет 1 и 4.Нельзя ли сделать такое же без вложенных запросов?

Edited by user
Link to comment
Share on other sites

13 answers to this question

Recommended Posts

  • 0

Поясню подробнее.Номер параметра-поле virtuemart_custom_id.Делается отбор по параметрам,например,3 и 4,которые соответствуют 1997 и Acura.Выбираются товары со значением Acura и из них выбираются товары со значением 1997 или наоборот.

Edited by user
Link to comment
Share on other sites

  • 0

Крайне трудно понять смысловую нагрузку запроса. Вот ТУПО переписанный запрос без вложенного подзапроса:

SELECT DISTINCT  t2.virtuemart_product_idFROM (  SELECT DISTINCT    virtuemart_product_id  FROM    #__virtuemart_product_customfields  WHERE    custom_value='ACURA'    AND virtuemart_custom_id=4) t1LEFT JOIN #__virtuemart_product_customfields t2  ON t1.virtuemart_product_id = t2.virtuemart_product_idWHERE  t2.custom_value='1997'  AND t2.virtuemart_custom_id=3

А если предположить, что есть таблица товаров и таблица дополнительных характеристик этих товаров и нужно получить неповторяющуюся выборку всех характеристик товаров, по нескольким характеристикам, тогда вот как-то так можно:

SELECT  -- Получаем все характеристики отобранных товаров  t2.*FROM (  -- Выбрать неповторяющее множество ид товаров по заданным характеристикам.  SELECT DISTINCT    virtuemart_product_id  FROM    #__virtuemart_product_customfields  WHERE    (custom_value='ACURA' AND virtuemart_custom_id=4)    OR (custom_value='1997' AND t2.virtuemart_custom_id=3)    -- Если еще нужно добавить критерии отбора, просто воткнуть еще одно условие    -- OR (custom_value='*****' AND t2.virtuemart_custom_id=****)) t1LEFT JOIN #__virtuemart_product_customfields t2  ON t1.virtuemart_product_id = t2.virtuemart_product_id
Edited by CoDy
  • Like 1
Link to comment
Share on other sites

  • 0

Совет: как по мне лучше так не "писать":

SELECT DISTINCT(virtuemart_product_id) FROM #__virtuemart_product_customfields

Лучше писать DISTINCT как модификатор к SELECT, а не как агригирующую функцию, в плане результата разницы нет абсолютно никакой, но так, я считаю, будет более корректно:

-- ваш случайSELECT DISTINCT virtuemart_product_id FROM #__virtuemart_product_customfields;-- илиSELECT DISTINCT c1, c2, c3  FROM t;
  • Like 1
Link to comment
Share on other sites

  • 0

да, это ошибка убрать нада t2 оттуда:

WHERE(custom_value='ACURA' AND virtuemart_custom_id=4)OR(custom_value='1997' AND virtuemart_custom_id=3)

Прочитал внимательно пояснение, если нужно выбрать все акуры 1997 года, тогда я написал неправильный запрос. Мой запрос вернет акуры или 1997. Если будет скрипт для создания таблицы, попробую написать правильный. Скрипт можно получить так:

show create table #__virtuemart_product_customfields;
Edited by CoDy
Link to comment
Share on other sites

  • 0
CREATE TABLE `j25_virtuemart_product_customfields` ( `virtuemart_customfield_id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'field id', `virtuemart_product_id` int(11) NOT NULL DEFAULT '0', `virtuemart_custom_id` int(11) NOT NULL DEFAULT '1' COMMENT 'custom group id', `custom_value` varchar(8000) DEFAULT NULL COMMENT 'field value', `custom_price` decimal(15,5) DEFAULT NULL COMMENT 'price', `custom_param` varchar(12800) DEFAULT NULL COMMENT 'Param for Plugins', `published` tinyint(1) NOT NULL DEFAULT '1', `created_on` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `created_by` int(1) unsigned NOT NULL DEFAULT '0', `modified_on` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `modified_by` int(1) unsigned NOT NULL DEFAULT '0', `locked_on` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `locked_by` int(1) unsigned NOT NULL DEFAULT '0', `ordering` int(2) NOT NULL DEFAULT '0', PRIMARY KEY (`virtuemart_customfield_id`), KEY `idx_virtuemart_product_id` (`virtuemart_product_id`), KEY `idx_virtuemart_custom_id` (`virtuemart_custom_id`), KEY `idx_custom_value` (`custom_value`(333))) ENGINE=MyISAM AUTO_INCREMENT=13701 DEFAULT CHARSET=utf8 COMMENT='custom fields'

Нужны данные?

Edited by user
Link to comment
Share on other sites

  • 0

Ну вот так, например:

SELECT  -- Получаем все характеристики отобранных товаров  t2.*FROM (  -- Выбрать неповторяющее множество ид товаров по заданным характеристикам.  -- Причем только те, у которых имеются все перечисленные характеристики.  SELECT    virtuemart_product_id,    count(*) AS eqvcnt  FROM    virtuemart_product_customfields  WHERE    -- Если еще нужно добавить критерии отбора, просто воткнуть еще одно условие    -- OR (custom_value='*****' AND t2.virtuemart_custom_id=****) и увеличить значение в    -- HAVING на 1     (virtuemart_custom_id=1 AND custom_value='1')    OR    (virtuemart_custom_id=2 AND custom_value='2')  GROUP BY     virtuemart_product_id   HAVING    eqvcnt = 2) t1INNER JOIN virtuemart_product_customfields t2  USING(virtuemart_product_id);-- илиSELECT  t2.*FROM (  SELECT    virtuemart_product_id,    count(*) AS eqvcnt  FROM    virtuemart_product_customfields  WHERE     (virtuemart_custom_id=1 AND custom_value='1')    OR    (virtuemart_custom_id=2 AND custom_value='2')  GROUP BY     virtuemart_product_id  ) t1InNER JOIN virtuemart_product_customfields t2  ON t1.virtuemart_product_id = t2.virtuemart_product_id AND t1.eqvcnt = 2

Первый запрос, думаю, будет по оптимальней. Проверяйте на реальных данных.

Edited by CoDy
  • Like 1
Link to comment
Share on other sites

  • 0

Вот еще вариант запроса, который в отличии от выше приведенных НЕ ПЕРЕЧИТЫВАЕТ полностью всю таблицу а пользует поиск по индексу:

SELECT  t3.*FROM  j25_virtuemart_product_customfields AS t1INNER JOIN  j25_virtuemart_product_customfields AS t2USING  (virtuemart_product_id)INNER JOIN      j25_virtuemart_product_customfields AS t3USING  (virtuemart_product_id)WHERE  t1.virtuemart_custom_id=1 AND t1.custom_value='1'  AND  t2.virtuemart_custom_id=2 AND t2.custom_value='2';

А если бы не было такого огромного поля `custom_value` varchar(8000), то запрос и таблицу можно было бы еще оптимизировать.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy