简体   繁体   English

LEFT JOIN 表,但如果条件不匹配则排除

[英]LEFT JOIN tables but exclude if conditions don't match

I have dynamic conditions.我有动态条件。 Sometimes there are conditions and sometimes not.有时有条件,有时没有。 I want to get all results from the left but exclude rows that do not match conditions.我想从左侧获取所有结果,但排除与条件不匹配的行。 Is there any way I can achieve this?有什么办法可以实现这一目标吗? With what I have it always gets all rows from the left.使用我所拥有的,它总是从左侧获取所有行。 If I use inner join it won't get the records from the base table if they can't join.如果我使用内部联接,则无法从基表中获取记录。 I need to be able to get all records from the anime table, however if there is a condition set, then only get the records that match the conditions.我需要能够从动漫表中获取所有记录,但是如果有条件集,则只获取与条件匹配的记录。

SELECT anime.id, anime.title, IF(english IS NULL or english = '', anime.title, english) as english, anime.slug
FROM anime
LEFT JOIN genres g ON g.anime_id = anime.id
LEFT JOIN episodes e ON e.anime_id = anime.id
LEFT JOIN videos v on v.episode_id = e.id
$conds
GROUP BY anime.id
ORDER BY $order
LIMIT $limit

$conds, $order, and $limit is the dynamically generated with php. $conds、$order 和 $limit 是用 php 动态生成的。

an example for a condition is条件的一个例子是

WHERE anime.status = 'completed' AND v.type = 'subbed'

The problem here is if I use left join the condition for v.type is completely ignored and it gets all records from the anime table.这里的问题是,如果我使用左连接,则 v.type 的条件将被完全忽略,它会从动漫表中获取所有记录。

Doing a left join will get all rows from the anime table regardless.无论如何,执行左连接将从动漫表中获取所有行。 But I want to not get all rows if there is a condition and only the rows that match the condition.但是如果有条件并且只有匹配条件的行,我不想获取所有行。 But if there is no conditions then get all rows anyways.但是,如果没有条件,则无论如何都要获取所有行。

If I use INNER JOIN instead of LEFT JOIN, if an anime has no episodes or videos it won't get them, but I NEED to get them.如果我使用 INNER JOIN 而不是 LEFT JOIN,如果动漫没有剧集或视频,它就不会得到它们,但我需要得到它们。

I had a similar trouble, you need to use EXISTS, as the following example:我也遇到过类似的问题,需要使用EXISTS,如下例:

SELECT t1.* FROM table_1 t1 
WHERE EXISTS (SELECT t2.* FROM table2 t2
WHERE t1.id=t2.t1_id AND t2.some_field='some value')

So your query should look like this:所以你的查询应该是这样的:

SELECT anime.id, anime.title, IF(english IS NULL or english = '', anime.title, english) as english, anime.slug
FROM anime
LEFT JOIN genres g ON g.anime_id = anime.id
LEFT JOIN episodes e ON e.anime_id = anime.id
WHERE EXISTS (SELECT v.* FROM videos v WHERE v.episode_id = e.id AND v.type = 'subbed')
AND anime.status = 'completed'
GROUP BY anime.id
ORDER BY $order
LIMIT $limit

i know that your question is old, but i submit this for anyone with a similar problem :)我知道你的问题很老,但我把这个提交给有类似问题的人:)

Maybe you need the following也许你需要以下

$query_with_condition = "SELECT ...
FROM anime
LEFT JOIN genres g ON g.anime_id = anime.id
LEFT JOIN episodes e ON e.anime_id = anime.id
LEFT JOIN videos v on v.episode_id = e.id
$conds
GROUP BY anime.id
ORDER BY $order
LIMIT $limit";

$query_without_condition = "SELECT ...
FROM anime
LEFT JOIN genres g ON g.anime_id = anime.id
LEFT JOIN episodes e ON e.anime_id = anime.id
LEFT JOIN videos v on v.episode_id = e.id
GROUP BY anime.id
ORDER BY $order
LIMIT $limit";

$result = mysql_query($query_with_condition, $conn);
$num_rows = mysql_num_rows($result);

// if the query with conditions doesn't return any rows
if(!$num_rows){
  // then we use the second query where no conditions
  $result = mysql_query($query_without_condition, $conn);
}

// use $result

I don't know but maybe you need the following我不知道,但也许您需要以下内容

WHERE anime.status = 'completed' AND IFNULL(v.type,'subbed') = 'subbed'

It also returns row from the left-table if this row haven't link with a video.如果该行没有与视频链接,它还会从左表返回行。

If I'm mistaken please, add test data for tables anime and videos .如果我弄错了,请为表animevideos添加测试数据。 And show an expected result for this data.并显示此数据的预期结果。

The "generic answer" is if you want the left join to "survive" a where clause condition you must also allow for NULL to be returned by the left join. “通用答案”是,如果您希望左连接“存活”一个 where 子句条件,您还必须允许左连接返回 NULL。

WHERE anime.status = 'completed' AND (v.type = 'subbed' OR v.type IS NULL)

nb: If you use functions to mimic the same effect then you removed access to indexes and that may badly affect query performance.注意:如果您使用函数来模拟相同的效果,那么您删除了对索引的访问,这可能会严重影响查询性能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM