【问题标题】:How to retrieve all records of joined table SQL如何检索连接表SQL的所有记录
【发布时间】:2019-10-18 20:34:21
【问题描述】:

所以我有 2 个表:customerpurchase。我想在购买时使用某些过滤器来获取客户及其所有购买;然而;如果有任何匹配过滤器,我想获取所有购买记录。

例如,如果我有 John Doe 在01/02/19 上购买了一次,在10/01/2019 上进行了另一次购买

目前我正在这样做:

SELECT * 
FROM customer LEFT JOIN Purchase 
on purchase ON purchase.customer_id = customer.id 
AND purchase.purchase_date = '2019-02-01'

但是,这只检索单次购买;当只有一个符合条件时,有没有办法检索所有购买?

谢谢

【问题讨论】:

  • 这是一个事实:'*' 和 'LEFT JOIN' 永远不会明智地出现在同一个查询中(哦,我刚刚想到了一个例外——但无论如何

标签: mysql sql


【解决方案1】:

我想你想要:

SELECT c.*, p.*
FROM customer c JOIN
     Purchase p
     ON p.customer_id = c.id 
WHERE EXISTS (SELECT 1
              FROM purchase p2
              WHERE p2.customer_id = c.id AND
                    p2.purchase_date = '2019-02-01'
             );

【讨论】:

    【解决方案2】:

    SELECT * FROM customer LEFT JOIN Purchase ON purchase.customer_id = customer.id还不够吗?

    或者您可能需要以下类似的东西:

    1. 如果您计划在特定日期购买所有商品,您可以这样做: SELECT * FROM customer LEFT JOIN Purchase ON purchase.customer_id = customer.id AND purchase.purchase_date IN ('2019-02-01', '2019-02-10', '2019-12-03')SELECT * FROM customer LEFT JOIN Purchase ON purchase.customer_id = customer.id WHERE purchase.purchase_date IN ('2019-02-01', '2019-02-10', '2019-12-03')

    2. 如果您计划在某个日期范围内获得所有购买:

    SELECT * FROM customer LEFT JOIN Purchase ON purchase.customer_id = customer.id AND (purchase.purchase_date BETWEEN '2019-02-01' AND '2019-02-10')

    注意括号很重要

    1. 如果您计划在任何购买日期都获得客户的所有购买,这应该足够了:

    SELECT * FROM customer LEFT JOIN Purchase ON purchase.customer_id = customer.id

    【讨论】:

      【解决方案3】:

      我会选择这样的连接:

      SELECT c.*, pc.* 
      FROM (
         SELECT DISTINCT customer_id 
         FROM purchase 
         WHERE purchase_date = '2019-02-01' 
      ) AS p0                                                     -- The filtered purchase(s)
      INNER JOIN customer AS c ON p0.customer_id = c.customer_id  -- The customers who made those purchases
      INNER JOIN Purchase AS pc ON c.customer_id = pc.customer_id -- All purchases by those customers
      ;
      

      从技术上讲,如果您实际上并不关心客户数据,则可以完全跳过该表。

      之所以需要子查询,是因为如果客户进行了多次满足 p0 条件的购买,则直接连接将生成其数据的多个副本。

      或者,您可以像这样使用相同的子查询:

      SELECT *
      FROM customer AS c 
      INNER JOIN Purchase AS pc ON c.customer_id = pc.customer_id
      WHERE c.customer_id IN (
         SELECT DISTINCT customer_id 
         FROM purchase 
         WHERE purchase_date = '2019-02-01' 
        )
      ;
      

      第二个的好处是它更直接地反映了任务的自然语言表达; “获取在 '2019-02-01' 购买的客户的所有客户购买数据”

      第一个也是,但有些人可能觉得它不自然,而且有点模棱两可; “对于 '2019-02-01' 的购买,查找所有购买数据的客户的购买数据”

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-02
        • 2022-01-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多