MySQL - Select 具有 JOIN 但 WHERE 子句适用于复杂且不同的边界的数据

MySQL - Select data with a JOIN but with WHERE clauses applying to complex and distinct perimeters

我有一个 MySQL 5.6 数据库,无法进行复杂查询,(我认为)涉及多个连接。

第一个 table (T1) 是 Hobby_ideas_articles,记录如下:

hobby_idea_article_id= 1,
hobby_id = 6
url= 'http://exo.example.com',
author = 'john@example.com'

hobby_idea_article_id= 2,
hobby_id = 3
url= 'http://exo.example2.com',
author = 'john@example.com'

hobby_idea_article_id= 3,
hobby_id = 6
url= 'http://exo.example3.com',
author = 'eric@example.com'

hobby_idea_article_id= 4,
hobby_id = 7
url= 'http://exo.example4.com',
author = 'john@example.com'

hobby_idea_article_id= 5,
hobby_id = 6
url= 'http://exo.example5.com',
author = 'nestor@example.com'

hobby_idea_article_id= 7,
hobby_id = 6
url= 'http://exo.example6.com',
author = 'ginger@example.com'

hobby_idea_article_id= 8,
hobby_id = 6
url= 'http://exo.example8.com',
author = 'derek@example.com'

hobby_idea_article_id= 9,
hobby_id = 6
url= 'http://exo.example9.com',
author = 'derek@example.com'

第二个 table (T2) 称为 Past_Customer_sent_messages 列出了过去的所有消息,特别是发送者的信息(customer_id -> 指向另一个 table 称为 Customers,在当前问题中不需要)和给谁(recipient),记录如下所示

past_customer_sent_message_id = 5
hobby_id = 7,
customer_id = 4,
recipient = "john@example.com",
sent_at= "2019-09-10 00:00:00"

past_customer_sent_message_id = 6
hobby_id = 999,
customer_id = 4,
recipient = "eric@example.com",
sent_at= "2019-09-18 00:00:00"

past_customer_sent_message_id = 7
hobby_id = 999,
customer_id = 4,
recipient = "nestor@example.com",
sent_at= "2019-07-18 00:00:00"

即使当前 T1 和 T2 之间没有外键,一个关键信息是 T1 'author''recipient" 如果客户向他发送消息,它将出现在 T2 上。

我不确定它对现在的问题是否重要,但是有一个 Customer table(一个 past_customer_sent_messages 属于一个 customer,一个 customer 有多个 past_customer_sent_messages) 和一个 Hobbies table (Hobby_ideas_article 属于 hobbyhobby 可以有多个 Hobby_ideas_articles).

在我的 javascript 文件中,在编写 SQL 语句之前,我 有 2 个已经给定值的输入,我需要在 SQL 语句:

我想要的是 Hobby_ideas_articles table (T1) 中检索所有记录,其中 hobby_id = HOBBY_ID_INPUT_I_HAVE 和 2 conditions/restrictions:

我觉得这部分在智力上特别具有挑战性,因为我很想把它作为 WHERE hobby_id = HOBBY_ID_INPUT_I_HAVE(见下文)但感觉不对,因为那样的话,我该如何实现适用于所有的条件 1消息,并且不应仅应用于那些 hobby_id = HOBBY_ID_INPUT_I_HAVE...hard! condition2 难度相同

也许我 could/should 添加一个名为 hobby_idea_id 的新列,我将把它放在 T2 上,它将作为 2 table 之间的外键作为 Past_Customer_sent_message在某种程度上属于 Hobby_ideas_article 并且 Hobby_ideas_article 有很多 Past_Customer_sent_messages ?

今天我有了这个,但我什至不知道在什么地方放置连接的 'ON' 子句...并且无法设置正确的语句。

SELECT             
          hia.query_result_id,
          hia.url,
          hia.title,
          hia.article_publication_day,
          hia.media_name,
          hia.author_full_name,
          hia.author_first_name,
          hia.author_last_name,
          hia.author_email,
          ces.sent_at
FROM
          Hobby_ideas_articles hia
LEFT JOIN
          Past_Customer_sent_messages ces
ON
          # WHAT CLAUSE ???
WHERE
          hia.hobby_id = HOBBY_ID_INPUT_I_HAVE AND         
          hia.author IS NOT NULL
          # more conditions but how to assert them ??

如何实现?

所需的输出将是:

hobby_idea_article_id= 5,
hobby_id = 6
url= 'http://exo.example5.com',
author = 'nestor@example.com'
last_email_sent_at = "2019-07-18 00:00:00"

hobby_idea_article_id= 7,
hobby_id = 6
url= 'http://exo.example6.com',
author = 'ginger@example.com'
last_email_sent_at = null

hobby_idea_article_id= 8,
hobby_id = 6
url= 'http://exo.example8.com',
author = 'derek@example.com'
last_email_sent_at = null

正如您在我的输入值中看到的那样(hobby_id = 6 , customer_id = 4),

免责声明:我来自 Rails 背景,我曾经有 ORM(活动记录)使所有 chains/joins/ 更容易 automagic 并且现在的 SQL 声明有点迷失,我必须在我的 javascript aws lambda 文件中写入。

使用recipient NOT IN (SELECT ...)author NOT IN (SELECT ...)排除符合条件1和2的参与者。

SELECT             
          hia.query_result_id,
          hia.url,
          hia.title,
          hia.article_publication_day,
          hia.media_name,
          hia.author_full_name,
          hia.author_first_name,
          hia.author_last_name,
          hia.author_email,
          ces.sent_at
FROM
          Hobby_ideas_articles hia
LEFT JOIN
          Past_Customer_sent_messages ces
ON
          hia.author = ces.recipient 
            AND ces.recipient NOT IN (
                SELECT recipient
                FROM Past_Customer_sent_messages
                WHERE sent_at > DATE_SUB(NOW(), INTERVAL 3 HOUR)
            )
WHERE
          hia.hobby_id = HOBBY_ID_INPUT_I_HAVE AND         
          hia.author IS NOT NULL
          AND hia.author NOT IN (
            SELECT recipient
            FROM Past_Customer_sent_messages
            WHERE customer_id = CUSTOMER_ID_INPUT_I_HAVE
            AND sent_at > DATE_SUB(NOW(), INTERVAL 30 DAY)
          )

ces 的条件必须在 ON 子句中,这样对于没有任何匹配行的文章,您将得到 sent_at = NULL