sql-query内部连接工作不正常

46qrfjad  于 2021-06-18  发布在  Mysql
关注(0)|答案(4)|浏览(251)

我有table table_tudo 以及 followItem ,在table上 table_tudo 我有一个专栏叫 tipo 可以有三个值之一 tipoEp, tipoOv and tipoFm ,在这两张table上 INNER JOINdateMD 以及 itemName 在这之后,我想在屏幕上只打印出与这个contidion匹配的itens table_tudo.dateMD > followItem.dateMD AND followItem.user_id = :user_id AND table_tudo.tipo = :tipoEp OR table_tudo.tipo = :tipoFm OR table_tudo.tipo = :tipoOv .
在我的查询结束时,我使用 GROUP BY 因为它显示了重复的行。
我不能使用 ANDINNER JOIN 两个表中的两列,然后我尝试使用 OR 它起作用了,但现在我有另一个问题,条件 table_tudo.dateMD > followItem.dateMD 不是为公司工作 table_tudo.tipo = :tipoFm OR table_tudo.tipo = :tipoOv 从这些 tipo 的都印在屏幕上,这个条件只适用于 table_tudo.tipo = :tipoEp .
我的问题怎么了?ps:内部变量 bindParam 是全局变量。

$MTEpPRP = $conn->prepare("SELECT * FROM `table_tudo` INNER JOIN `followItem` ON `table_tudo`.`itemName` = `followItem`.`itemName` OR `table_tudo`.`dateMD` = `followItem`.`dateMD` WHERE `table_tudo`.`dateMD` > `followItem`.`dateMD` AND `followItem`.`user_id` = :user_id AND `table_tudo`.`tipo` = :tipoEp OR `table_tudo`.`tipo` = :tipoFm OR `table_tudo`.`tipo` = :tipoOv GROUP BY `table_tudo`.`id`");
$MTEpPRP->bindParam(':tipoEp', $tipoEp, PDO::PARAM_STR);
$MTEpPRP->bindParam(':tipoFm', $tipoFm, PDO::PARAM_STR);
$MTEpPRP->bindParam(':tipoOv', $tipoOv, PDO::PARAM_STR);
$MTEpPRP->bindParam(':user_id', $user_id, PDO::PARAM_INT);      
$MTEpPRP->execute();

我做了一些测试,我也意识到 table_tudo.tipo = :tipoFm OR table_tudo.tipo = :tipoOv 只有当我的查询中有这一行时,才会在屏幕上打印出来 table_tudo.tipo = :tipoEp .
我认为问题出在 INNER JOIN 因为我在下面测试了这些查询,结果成功了:

$MTEpPRP = $conn->prepare("SELECT * FROM `table_tudo` WHERE `table_tudo`.`tipo` = :tipoOv");    
$MTEpPRP->bindParam(':tipoOv', $tipoOv, PDO::PARAM_STR);
$MTEpPRP->execute();

$MTEpPRP = $conn->prepare("SELECT * FROM `table_tudo` WHERE `table_tudo`.`tipo` = :tipoFm");  
$MTEpPRP->bindParam(':tipoFm', $tipoFm, PDO::PARAM_STR);
$MTEpPRP->execute();

$MTEpPRP = $conn->prepare("SELECT * FROM `table_tudo` WHERE `table_tudo`.`tipo` = :tipoFm OR `table_tudo`.`tipo` = :tipoOv");  
$MTEpPRP->bindParam(':tipoFm', $tipoFm, PDO::PARAM_STR);
$MTEpPRP->bindParam(':tipoFm', $tipoOv, PDO::PARAM_STR);
$MTEpPRP->execute();
wz1wpwve

wz1wpwve1#

试试这样的。

select * from table_tudo t
inner join followItem f on  t.itemName = f.itemName 
where f.dateMD > t.dateMD 
and f.user_id  = 'user_id' and (t.tipo ='tipoEp' or t.tipo ='tipoFm' or t.tipo 
='tipoOV' )
1u4esq0p

1u4esq0p2#

您的主要查询基本上是正确的。这里的格式是为了更容易阅读表的相关性。我还为表名添加了别名以简化。t和fi(别名)表之间的连接只是那些限定记录的连接。。。匹配的id,用户和日期更大。这是第一部分。
接下来是对“tipo”限定符的限制。我将此更改为使用in子句,因此如果tipo是列表中的任何一个,则为真。

SELECT 
      * 
   FROM 
      table_tudo T
         INNER JOIN followItem FI
            ON T.itemName = FI.itemName
            AND FI.user_id = :user_id 
            AND T.dateMD > FI.dateMD 
   WHERE 
      T.tipo IN ( :tipoEp, :tipoFm, :tipoOv )
   GROUP BY 
      T.id

您可能遇到记录未正确返回的问题的原因是,在所有AND之后都有or条件,但没有任何括号。因此,当它有一个匹配,它加入了全面,可能在笛卡尔的结果。
在分组方式中,您需要添加每个表中的列列表,以帮助限制重复,以及您关心哪个表中的列。

ioekq8ef

ioekq8ef3#

与目标描述相比,查询中存在以下几个问题:
你的join中的2个条件需要 AND ,不是 OR . 也是最 WHERE 条件可以直接移动到 JOIN ,使逻辑更容易理解
您的系统中的操作员预见问题 WHERE 条款;你需要把这封信封起来 OR 参与其中,否则它不会像你想的那样 ... AND ( 图多表 . 提波 = :tipoEp OR 图多表 . 提波 = :tipoFm OR 图多表 . 提波 = :tipoOv). Better yet, use an 从句,哪个更容易读
更新的查询:

SELECT 
    * 
FROM 
    `table_tudo`
    INNER JOIN `followItem` 
        ON `table_tudo`.`itemName` = `followItem`.`itemName` 
        AND `table_tudo`.`dateMD` = `followItem`.`dateMD`
        AND `table_tudo`.`dateMD` > `followItem`.`dateMD`
        AND `followItem`.`user_id` = :user_id 
    WHERE  
        `table_tudo`.`tipo` IN (:tipoEp, :tipoFm, `table_tudo`.`tipo` = :tipoOv )
    GROUP BY `table_tudo`.`id`

ps:我怀疑 GROUP BY 是有用的,试着移除它,看看会发生什么。

2fjabf4q

2fjabf4q4#

你要求的日期要大于等于同一时间
您可能需要在或条件中使用括号来控制它们的解释方式。
您依赖mysql的非标准groupby来过滤不需要的行,但这些只是近似值。

SELECT *
FROM `table_tudo`
INNER JOIN `followItem` ON `table_tudo`.`itemName` = `followItem`.`itemName`

   OR `table_tudo`.`dateMD` = `followItem`.`dateMD`   << not making sense
WHERE `table_tudo`.`dateMD` > `followItem`.`dateMD`   << not making sense

 AND `followItem`.`user_id` = :user_id
 AND (                                     << use parentheses
      `table_tudo`.`tipo` = :tipoEp
   OR `table_tudo`.`tipo` = :tipoFm
   OR `table_tudo`.`tipo` = :tipoOv
     )                                     << use parentheses
GROUP BY `table_tudo`.`id`                 << select * with group by is MySQL nightmare

请参见:https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html

相关问题