简体   繁体   English

MySQL缺席情况下的外部联接

[英]MySQL Left Outer Join with Absence Condition

Overview 概观

I'm simplifying the description of my application to make the query clearer. 我正在简化应用程序的描述,以使查询更清晰。 The application stores saved phrases . 该应用程序存储已保存的phrases These phrases are each assigned a category . 这些短语分别分配有一个category The phrases can be posted by users . 短语可以由users posted An English description of my query: 我的查询的英文说明:

I need to pass a category and user into the prepared statement . 我需要将categoryuser传递到prepared statement The result will include only phrases with the category passed as an argument. 结果将仅包含category作为参数传递的phrases From the phrases of this category , only phrases will be returned where there does not exist any posted instances of this phrase for the user argument with the timePosted field in the last two weeks. phrases此的category ,只有phrases将返回那里不存在此的任何发布实例phraseuser的说法timePosted领域在过去的两个星期。

Minimal Schema 最小架构

savedPhrase savedPhrase

  • phraseIdentifier - INT UNSIGNED 短语标识符-INT无符号
  • textContent - VARCHAR textContent-VARCHAR
  • associatedCategory - VARCHAR relatedCategory-VARCHAR
  • ___primary key is phraseIdentifier ___primary key是短语标识符

postedPhrase postedPhrase

  • savedPhrase - INT UNSIGNED - foreign key references savedPhrase(phraseIdentifier) savedPhrase-INT未签名-外键引用savePhrase(phraseIdentifier)
  • username - VARCHAR 用户名-VARCHAR
  • timeReposted - TIMESTAMP timereposted-TIMESTAMP
  • ___primary key is combination of all listed fields ___primary key是所有列出字段的组合

Current Best Attempt with Behavior 当前的最佳尝试行为

I'm self-taught/learning MySQL and believe I struggle with joins . 我是自学/学习MySQL的人,并且相信我在joins很挣扎。 I think I should be using at least one left outer join as seen in the graphic below. 我认为我应该至少使用一个left outer join ,如下图所示。 The left table will be savedPhrase and the right will be postedPhrase . 左边的表将为savedPhrase ,右边的表将为postedPhrase

左外连接

SELECT * FROM savedPhrase S 
LEFT JOIN postedPhrase P
ON (S.phraseIdentifier = P.savedPhrase AND P.username = ?)
WHERE
(P.savedPhrase IS NULL OR P.timeReposted < DATE_SUB(NOW(), INTERVAL 14 day)) AND
S.associatedCategory = ?

The query above ALMOST works. ALMOST上面的查询有效。 However, once a single postedPhrase row exists at least two weeks ago, it will return the joined savedPhrase , even if one has been posted on the same account with the same identifier less than two weeks ago. 但是,一旦至少在两周前存在一个postedPhrase行,即使少于两个星期前将一个行以相同的标识符发布到了具有相同标识符的同一个帐户中,它也将返回加入的savedPhrase

Further Discussion 进一步讨论

The place where I'm having difficulty is the "absence condition". 我遇到困难的地方是“缺席状况”。 This is where a savedPhrase must not exist within the last two weeks. 这是过去两周内不得存在savedPhrase地方。 In the previous paragraph I explained how the absence is not functioning because the postedPhrase s are being returned based on their own independent timeReposted . 在上一段中,我解释了缺少的原因,因为postedPhrase是基于它们自己独立的timeReposted返回的。 It seems I should be adding the absence condition to the right circle of the left outer join. 似乎我应该在左外部连接的右圆上添加缺席条件。 Simplification of when to apply the conditions to the ON versus the WHERE would be very helpful. 简化何时将条件应用于ONWHERE将非常有帮助。

I've worked at fixing this problem for a while and would appreciate any direction. 我已经为解决这个问题工作了一段时间,希望能对您有所帮助。 Please let me know if I can include any other information. 请让我知道是否可以提供其他信息。

You don't have to to use JOIN to archive the result that you want. 您无需使用JOIN即可存档所需的结果。 You could write the query base on the English description of the query which described on your question. 您可以根据问题的英语说明来编写查询。

SELECT S.* 
FROM   savedPhrase S 
WHERE  S.associatedCategory = ? 
       AND NOT EXISTS (SELECT 1 
                       FROM   postedPhrase P 
                       WHERE  P.username = ? 
                              AND S.phraseIdentifier = P.savedPhrase 
                              AND P.timeReposted >= DATE_SUB(NOW(), 
                                                    INTERVAL 14 day))

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

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