2015-12-10 4 views
0

Я пытаюсь вернуть 10 лучших брендов, которые делят «идентификатор транзакции» с выбранным брендом (брендом $). Я начал с базового запроса, который запрашивает 1 таблицу с идентификаторами столбцов и брендом.mysql right join query return no values ​​

Теперь я хочу, чтобы это работало на 2 отдельных таблицах (один для транзакций и продуктов соответственно), с общим полем (sku).

Я начал с этого запроса, чтобы получить исходную логику (кредит для вкладчика stackoverflow), и он отлично работает.

$brand = $_POST['brand']; 
$query = $db->prepare("SELECT brand 
FROM transactions 
WHERE 
id IN (SELECT id FROM transactions WHERE brand = :brand) 
AND brand <> :brand 
GROUP BY brand 
ORDER BY COUNT(*) DESC 
LIMIT 10"); 
$query->bindparam(":brand", $brand); 
$query->execute(); 

Вышеупомянутые работы отличные, как я уже упоминал. И я немного изменил его, чтобы включить связанные таблицы. НО, это не работает. и не возвращает значений.

Любой принимает. Высокая оценка - Адам

$brand = $_POST['brand']; 
$query = $db->prepare("SELECT `2_products`.`brand` 
FROM `2_products` 
RIGHT JOIN `1_txns` 
ON `2_products`.`sku`=`1_txns`.`sku` 
WHERE 
`1_txns`.`txn_id` IN (SELECT `1_txns`.`txn_id` FROM `1_txns` WHERE `2_products`.`brand` = :brand) 
AND `2_products`.`brand` <> :brand 
GROUP BY `2_products`.`brand` 
ORDER BY COUNT(*) DESC 
LIMIT 10"); 
$query->bindparam(":brand", $brand); 
$query->execute(); 

Я понимаю, что может быть и другими методами для этого, например, создать временную таблицу, с помощью всего txn_id и brand колонн, но я опять не знаю, как это сделать.

отредактируйте попытку # 2 - здесь, как указано ниже, я переместил AND 2_products. brand <>: бренд сразу после предложения ON. Еще 0 строк.

$brand = $_POST['brand']; 
$query = $db->prepare("SELECT `2_products`.`brand` 
FROM `2_products` 
RIGHT JOIN `1_txns` 
ON `2_products`.`sku`=`1_txns`.`sku` 
AND `2_products`.`brand` <> :brand 
WHERE `1_txns`.`txn_id` IN (SELECT `1_txns`.`txn_id` FROM `1_txns` WHERE `2_products`.`brand` = :brand) 
GROUP BY `2_products`.`brand` 
ORDER BY COUNT(*) DESC 
LIMIT 10"); 
$query->bindparam(":brand", $brand); 
$query->execute(); 

EDIT 3: Кроме того, принимая во внимание тот факт, что в моем внутреннем выберите запрос, где положение является столбец, который не выбран из внутреннего запроса. и поэтому я попытался это: На что я получил ошибку «Операнд должен содержать только 1 столбец (ы)»

SELECT `2_products`.`brand` 
FROM `2_products` 
RIGHT JOIN `1_txns` 
ON `2_products`.`sku`=`1_txns`.`sku` 
AND `2_products`.`brand` <> :brand 
WHERE `1_txns`.`txn_id` IN (SELECT `1_txns`.`txn_id`, `2_products`.`brand` 
          FROM `1_txns` 
          LEFT JOIN `2_products` 
          ON `1_txns`.`sku`=`2_products`.`sku` 
          WHERE `2_products`.`brand` = :brand) 
GROUP BY `2_products`.`brand` 
ORDER BY COUNT(*) DESC 
LIMIT 10; 
+0

Ваш внутренний запрос неверен. У вас есть столбец в предложении 'where', таблица которого не включена в ваше предложение' from'. Таким образом, это не сработает. –

+0

Удалите из внутреннего выбора «2_products'.'brand'». Вы не можете вернуть более одного поля в свой внутренний запрос.Это избавит вас от ошибки, но трудно определить проблему, не видя реальных данных, которые у вас есть на таблицах. – Marcovecchio

+0

Возможно, мой внутренний запрос является проблемой при попытке использовать этот метод для 2 связанных таблиц, а не для одного, у которого есть только два столбца? как сказал Прерак, предложение where определяет столбец, который не находится во внутреннем выборе? –

ответ

0

Эта задача была решена в следующем вопросе о dba.stackexchange

DBA Question

0

Когда LEFT/RIGHT присоединиться не возвращают записи, сначала проверьте, если WHERE имеет какие-либо фильтры, относящиеся к стол на «слабой» стороне. Под «слабым» я имею в виду правый стол на LEFT JOIN или левую таблицу на RIGHT JOIN.

В вашем случае левый стол 2_products, поэтому он может генерировать NULL-поля, но в WHERE у вас есть 2_products.brand <> :brand. Если это условие не удастся, запись будет удалена.

Чтобы избежать этого, попробуйте перевести это условие в предложение ON после 2_products.sku=1_txns.sku, так как фильтрация там не будет удалена, если условие не выполнено. Он должен выглядеть так:

ON 2_products.sku=1_txns.sku AND 2_products.brand <> :brand

И ИНЕКЕ должно выглядеть следующим образом:

WHERE 1_txns.txn_id IN (SELECT 1_txns.txn_id FROM 1_txns WHERE 2_products.brand = :brand)

+0

Я только что пошел на это, и до сих пор никаких записей не было. См. Мое редактирование в нижней части исходного вопроса. Многие Спасибо -A –

+0

@AdamCopley, я хотел переместить только условие в предложение ON, а не все WHERE. См. Изменение, которое я сделал по моему ответу. – Marcovecchio

+0

Я попробовал ваше решение и все еще не получил результатов. Я также попытался что-то сказать о замечании Прерака Солы и возвратил ошибку. –