Mysql SQL查询、有效期和联接:如何使其工作?

Mysql SQL查询、有效期和联接:如何使其工作?,mysql,sql,Mysql,Sql,以下三个表都有一个“日期\u v\u结束”字段,该字段是有效日期。只要它是NULL这意味着它是当前的“良好”值 例如,要选择表category的当前值,我们只需执行select*FROM category,其中date\v\u end为NULL 我有三张桌子: 表分类(英语分类) 表“一对多”分类产品(英语分类产品) 表produit(英文产品) 我想查询所有当前的类别,以及它们的一对多produit,即使该类别没有产品(=noproduit\u categorie行),我仍然需要一个结果

以下三个表都有一个“
日期\u v\u结束
”字段,该字段是有效日期。只要它是
NULL
这意味着它是当前的“良好”值

例如,要选择表
category
的当前值,我们只需执行
select*FROM category,其中date\v\u end为NULL

我有三张桌子:

  • 分类
    (英语分类)
  • 表“一对多”
    分类产品
    (英语分类产品)
  • produit
    (英文产品)
我想查询所有当前的
类别
,以及它们的一对多
produit
,即使该类别没有产品(=no
produit\u categorie
行),我仍然需要一个结果

在使用“
日期\u v\u结束
”字段之前,我是这样做的:

SELECT
  c.id AS c_id,
  c.titre AS c_titre,
  c.description AS c_description,
  cp.id_categorie AS cp_id_categorie,
  cp.id_produit AS cp_id_produit,
  p.id AS p_id,
  p.titre AS p_titre,
  p.description AS p_description
FROM categorie_produit cp
LEFT OUTER JOIN categorie c
ON c.id=cp.id_categorie
LEFT OUTER JOIN produit p
ON p.id=cp.id_produit
ORDER BY c_id,p_id;
它就像一个符咒。现在我正试图用新的“
date\u v\u end
”字段修改查询。我添加了三个子句
,其中c.date\u v\u fin为NULL,cp.date\u v\u fin为NULL,p.date\u v\u fin为NULL
。好了:

SELECT
  c.id AS c_id,
  c.titre AS c_titre,
  c.description AS c_description,
  cp.id_categorie AS cp_id_categorie,
  cp.id_produit AS cp_id_produit,
  p.id AS p_id,
  p.titre AS p_titre,
  p.description AS p_description
FROM categorie_produit cp
LEFT OUTER JOIN categorie c
ON (c.id=cp.id_categorie AND c.date_v_fin IS NULL)
LEFT OUTER JOIN produit p
ON (p.id=cp.id_produit AND p.date_v_fin IS NULL)
WHERE cp.date_v_fin IS NULL
ORDER BY c_id,p_id;
除了一种情况外,这种方法很有效:当有一个
categorie\u produit
并且它的“
date\u v\u end
”不是
NULL
:在添加这个该死的“
date\u v\u end
”字段之前,我得到了一行,其中填充了c\u id、c\u titre和c\u description,其他字段
NULL
cp\u id\u category
cp\u id\u produit
p\u id
p\u titre
p\u description
),现在没有结果了


我真的不知道如何修改我的查询以使其正常工作。有什么想法吗?

您需要将
为NULL
检查移到联接中

在您的版本中,您可以加入,而不考虑
date\u v\u fin
字段,然后过滤结果

在下面的查询中,仅当date_v_fin字段为空时,才会连接记录

SELECT
  c.id AS c_id,
  c.titre AS c_titre,
  c.description AS c_description,
  cp.id_categorie AS cp_id_categorie,
  cp.id_produit AS cp_id_produit,
  p.id AS p_id,
  p.titre AS p_titre,
  p.description AS p_description
FROM
  categorie c
LEFT OUTER JOIN
  categorie_produit cp
    ON  c.id=cp.id_categorie
    AND cp.date_v_fin IS NULL
LEFT OUTER JOIN
  produit p
    ON  p.id=cp.id_produit
    AND p.date_v_fin IS NULL
WHERE
  c.date_v_fin IS NULL
ORDER BY
  c_id,
  p_id

您需要将
IS NULL
检查移动到联接中

在您的版本中,您可以加入,而不考虑
date\u v\u fin
字段,然后过滤结果

在下面的查询中,仅当date_v_fin字段为空时,才会连接记录

SELECT
  c.id AS c_id,
  c.titre AS c_titre,
  c.description AS c_description,
  cp.id_categorie AS cp_id_categorie,
  cp.id_produit AS cp_id_produit,
  p.id AS p_id,
  p.titre AS p_titre,
  p.description AS p_description
FROM
  categorie c
LEFT OUTER JOIN
  categorie_produit cp
    ON  c.id=cp.id_categorie
    AND cp.date_v_fin IS NULL
LEFT OUTER JOIN
  produit p
    ON  p.id=cp.id_produit
    AND p.date_v_fin IS NULL
WHERE
  c.date_v_fin IS NULL
ORDER BY
  c_id,
  p_id

这太不可思议了。我觉得自己太愚蠢了。我已经花了两个多小时在这上面了,因为我不想问stackoverflow(骄傲的问题)。看到像你这样的人回答得这么快,而且回答正确,这几乎是一种耻辱。)我们有时都会被显而易见的事情蒙蔽了双眼。嗯,我大部分时间都被显而易见的事情蒙蔽了双眼……我想这是双向的。虽然我们可能被显而易见的事物蒙蔽了双眼,但我们也可能有机会通过指出显而易见的事物来展示我们的思维机敏和对相关领域的渗透。然后得到一些可疑的赞美,比如@Olivier's.:)太不可思议了。我觉得自己很愚蠢。我已经为此工作了2个多小时,因为我不想问stackoverflow(骄傲的问题)。看到像你这样的人用正确的答案回答得如此之快,几乎是一种耻辱WHERE子句不会使那些
内部联接
s(有效)-移动
cp.date\u v\u fin
p.date\u v\u fin
检查到它们各自的
联接
子句怎么样?您不希望该行,因为它无效吗?或者您甚至没有得到“正确”的行?除此之外,将比较添加到
WHERE
子句中不会使那些
内部联接(有效)-将
cp.date\u v\u fin
p.date\u v\u fin
检入各自的
JOIN
子句怎么样?