MySQL - 结构化查询以丢弃常见结果


MySQL - structuring query to discard common results

这个标题真的没有用,但这是一个复杂的问题(在我的脑海中,也许(......随便...

假设我有一个带有ID和名称的国家/地区(世界上所有国家/地区的A-Z(的MySQL表

然后我有一个表格,我正在跟踪用户去过哪些国家/地区:像这样:

    Country Table
    id    name
    1     india
    2     luxembourg
    3     usa
    Visited Table
    id    user_id    country_id    
    1     1          1
    2     1          3

现在这就是我想做的,当我出示表格以添加到访问的国家/地区列表中时,我希望 country.id 1 和 3 从查询结果中排除。

我知道我可以使用PHP过滤它...这是我过去做过的事情...但肯定必须有一种方法可以构建查询,以便从返回的结果中排除 1 和 3,例如:

    SELECT * 
      FROM `countries` 
     WHERE `id`!= "SELECT `country_id` 
                     FROM `visited` 
                     WHERE `user_id`='1'"

我怀疑它与 JOIN 语句有关,但我不太清楚。

如果有人能用拉拉维尔为我指出正确的方向,我将不胜感激。

谢谢大家:)

这是你想要的吗?

select c.*
from countries c left join
     visited v
     on c.id = v.country_id and v.user_id = 1
where v.country_id is null;

您也可以将其表示为not innot exists,但left join方法通常具有相当不错的性能。

左外部连接保留第一个表中的所有记录,而不管 on 子句的计算结果是否为 true。 如果第二个表中没有匹配项,则使用NULL值填充列。 where子句只是选择这些记录 - 不匹配的记录。

以下是另一种表达方式,您可能会发现它更容易理解:

select c.*
from countries c
where not exists (select 1 from visited where c.id = v.country_id and v.user_id = 1)

您可以像这样使用查询。

SELECT * 
  FROM `countries` c LEFT JOIN `visited` v on c.id = v.country_id
 WHERE v.`country_id` is null
   AND v.`user_id` = 1

这是左联接的操作。这意味着我根据国家/地区的 ID 从表中countries选择所有注册表,这些注册表可能在表上,也可能不在表visited上。

所以它会给你带来这个群体

from country      from visited
     1                 1
     2              no registry
     3                 3

所以在 where 条件 ( v.country_id is null ( 我说:我只想要这个左侧连接操作仅在国家/地区表上但不在访问表上的那些,所以它给我带来了 id 2.加上条件,即访问的注册表必须来自user_id=1

SELECT * FROM COUNTRIES LEFT JOIN 
VISITED ON 
countries.id = visited.country_id and visited.country_id NOT IN ( SELECT country_id FROM visited )

如果我理解正确,也许你需要这样的东西?