rpsv
@rpsv
делай либо хорошо, либо никак

Как выполнить подзапрос к той же таблице?

Здрасте!

Колдую над битриксовой таблицей b_iblock_element_property (ее структура ниже). Задача в следующем: у модели имеются 2 свойства (id_site, id_advert их идентификаторы для поля IBLOCK_ELEMENT_ID: 22, 23 соответственно). Нужно получить id_advert для всех элементов у которых id_site = X.

Структура таблицы:
spoiler
CREATE TABLE `b_iblock_element_property` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `IBLOCK_PROPERTY_ID` int(11) NOT NULL,
  `IBLOCK_ELEMENT_ID` int(11) NOT NULL,
  `VALUE` text NOT NULL,
  `VALUE_TYPE` char(4) NOT NULL DEFAULT 'text',
  `VALUE_ENUM` int(11) DEFAULT NULL,
  `VALUE_NUM` decimal(18,4) DEFAULT NULL,
  `DESCRIPTION` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`ID`),
  KEY `ix_iblock_element_property_1` (`IBLOCK_ELEMENT_ID`,`IBLOCK_PROPERTY_ID`),
  KEY `ix_iblock_element_property_2` (`IBLOCK_PROPERTY_ID`),
  KEY `ix_iblock_element_prop_enum` (`VALUE_ENUM`,`IBLOCK_PROPERTY_ID`),
  KEY `ix_iblock_element_prop_num` (`VALUE_NUM`,`IBLOCK_PROPERTY_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=507 DEFAULT CHARSET=cp1251


Запросы:
spoiler

Запрос для выборки элементов с "id_site = 1":
SELECT *
FROM b_iblock_element_property
WHERE IBLOCK_PROPERTY_ID = 22 AND value = 1


Запрос для получения "id_advert":
SELECT DISTINCT value as id_advert
FROM b_iblock_element_property
WHERE IBLOCK_PROPERTY_ID = 23


А вот теперь интрига: как это все подружить? Подзапрос не хочет работать (вероятно проблема с "ссылками" на таблицу):
SELECT DISTINCT value as id_advert
FROM b_iblock_element_property
WHERE IBLOCK_PROPERTY_ID = 23 AND ID IN (
  SELECT t2.id
  FROM b_iblock_element_property as t2
  WHERE t2.IBLOCK_PROPERTY_ID = 22 AND t2.value = 1
)


С джойнами тоже не получается, только если использовать cross join:
SELECT DISTINCT t1.value as id_advert
FROM b_iblock_element_property as t1, b_iblock_element_property as t2
WHERE t1.IBLOCK_PROPERTY_ID = 23 AND t2.IBLOCK_PROPERTY_ID = 22 AND t2.value = 1



Подскажите как можно эту задачку решить лучше?
  • Вопрос задан
  • 1022 просмотра
Решения вопроса 2
@dmitryKovalskiy
программист средней руки
SELECT t1.value as id_advert
FROM b_iblock_element_property as t1
INNER JOIN  b_iblock_element_property as t2 ON t2.value = 1 AND t2.IBLOCK_PROPERTY_ID = 22
WHERE t1.IBLOCK_PROPERTY_ID = 23
GROUP BY  t1.value

Примерно так пробовали JOIN делать???
Кстати, рекомендую подзабыть слово DISTINCT и пользоваться GROUP BY
Ответ написан
rpsv
@rpsv Автор вопроса
делай либо хорошо, либо никак
После долгой и бессмысленной переписи с Сергей я все-таки решил использовать API, и оказывается с помощью него можно (и довольно лаконично) решить поставленную задачу:

$dbRes = CIBlockElement::GetList(
    null,
    array(
        "IBLOCK_ID" => 3,
        "PROPERTY_id_site" => 1
    ),
    array("PROPERTY_id_advert"),
    array("nTopCount" => 3),
    array("PROPERTY_id_advert")
);


При чем показатели EXPLAIN не слишком отличаются
(https://habrastorage.org/files/fff/ab3/5ae/fffab35... ).
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
sabramovskikh
@sabramovskikh
Чем API не угодил, что нужно извращаться с SQL?
Ответ написан
@Wol_fi
php, js, mysql, highload
SELECT DISTINCT value as id_advert
FROM b_iblock_element_property
WHERE IBLOCK_PROPERTY_ID = 23 AND ID IN (
SELECT t2.id
FROM b_iblock_element_property as t2
WHERE t2.IBLOCK_PROPERTY_ID = 22 AND t2.value = 1
)

SELECT DISTINCT value as id_advert
FROM b_iblock_element_property
INNER JOIN (
   SELECT t2.ID
  FROM b_iblock_element_property as t2
  WHERE t2.IBLOCK_PROPERTY_ID = 22 AND t2.value = 1
) AS x USING (ID)
WHERE IBLOCK_PROPERTY_ID = 23

Так попробуйте
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы