Можно ли сравнить два разных ряда при левостороннем соединении? - PullRequest
0 голосов
/ 22 февраля 2012

Таблица 1 -> идентификатор, имя
Таблица 2 -> идентификатор, имя, text_value, table1_id, table3_id
Таблица 3 -> идентификатор, имя

SELECT * FROM `table1`   
LEFT OUTER JOIN table2 ON table1.id = table2.table1_id   
WHERE 
 (
     (table2.table3_id = '7' AND table2.name like ('%test%'))
 )   
  AND 
 (
      table2.table3_id = '1' and table2.text_value like ('%fast update%'))
 )   
GROUP BY table1.id  
ORDER BY table1.id desc

Ответы [ 3 ]

1 голос
/ 22 февраля 2012

Да, но для этого нужно два объединения:

  • Поскольку вы будете присоединяться к таблице 2 дважды, одно из объединений должно использовать псевдоним.Я выбрал t2.
  • Измените AND на LEFT OUTER JOIN table2 AS t2 ON.
  • В оставшейся части запроса измените table2 на t2.
  • При использовании GROUP BY все указанные вами столбцы должны быть либо в предложении GROUP BY, либо в совокупности.Поскольку вы этого не сделали, и неясно, почему вы пытались использовать GROUP BY, я исключаю предложение GROUP BY.

Есть несколько других изменений.Смотрите окончательный запрос ниже:

SELECT
  table1.id
FROM
  table1
    LEFT OUTER JOIN
  table2
    ON table1.id = table2.table1_id
    LEFT OUTER JOIN
  table2 t2
    ON table1.id = t2.table1_id
WHERE
  table2.table3_id = '7'
    and
  table2.name like '%test%'
    AND
  t2.table3_id = '1'
    and
  t2.text_value like '%fast update%'
ORDER BY
  table1.id DESC
1 голос
/ 22 февраля 2012

Краткий ответ, да.

Более длинный ответ, перечитав ваш вопрос несколько раз, следующий будет работать, но не будет самым эффективным запросом в мире, я настоятельно призываю вас пересмотреть то, что вы пытаетесь выполнить, ибудет ли хорошей идеей реструктуризация таблицы.

Я выбрал INNER JOIN, поскольку вас интересуют только строки, соответствующие обоим критериям, и поэтому строки NULL не важны.Предложение HAVING обеспечивает вывод только тех строк, которые совпадают с обоими, в то время как ограничения table2 в предложении ON помогают ограничить влияние на производительность.

SELECT 
    table1.*,
    COUNT(DISTINCT(table3.id)) AS numberOfMatches 
FROM table1


INNER JOIN table2 
ON table2.table1_id = table1.id
AND (
    (table2.table3_id = 7 AND table2.name LIKE '%test%') 
    OR 
    (table2.table3_id = 1 AND table2.text_value LIKE '%fast update%')
)

INNER JOIN table3
ON table3.id = table2.table3_id

GROUP BY table1.id
HAVING numberOfMatches = 2
ORDER BY table1.id DESC
0 голосов
/ 22 февраля 2012
SELECT * 
FROM `table1` a LEFT OUTER JOIN table2 b ON a.id = b.table1_id   
WHERE 
 (
     b.table3_id = '7' AND b.name like '%test%'
 )   
  AND 
 (
      b.table3_id = '1' and b.text_value like '%fast update%'
 )   
GROUP BY a.id  
ORDER BY a.id desc
...