繁体   English   中英

如何通过count限制SQL LEFT JOIN查询的结果集

[英]How to limit result set of an SQL LEFT JOIN query by count

我希望使用LEFT JOIN查询从两个具有一对多关系的表中获取一些结果,但是根据“子”的数量来限制结果集。 我有两个表格结构如下:

customers
id    name    ...
1     "bob"   ...
2     "jill"  ...

orders
id    customer_id    ...
100   1              ...
101   2              ...
102   1              ...

(表中的其余数据与此查询无关。)

我想要做的是获取所有客户ID及其订单ID,按客户排序, 但仅限于已订购多个订单的客户。 在此示例中,结果如下所示:

cust_id    order_id
1          100
1          102

我已经开始使用基本LEFT JOIN将订单ID与其客户配对,但无法弄清楚如何将所有未订购至少两次的客户排除在外。

SELECT 
    `customers`.`id` AS `cust_id`,
    `orders`.`id` AS `order_id`
FROM
    `customers`
LEFT JOIN `orders` ON
    `customers`.`id` = `orders`.`customer_id`
ORDER BY
    `cust_id`

谢谢大家。

一种方法是创建一个内联视图,该视图可以获得具有多个订单的客户以及具有多个订单的内部联接。 如果你不喜欢JOIN,你也可以做IN或EXISTS

SELECT 
    `customers`.`id` AS `cust_id`,
    `orders`.`id` AS `order_id`
FROM
    `customers`
LEFT JOIN `orders` ON
    `customers`.`id` = `orders`.`customer_id`
INNER JOIN 
      (SELECT `customer_id `    
       FROM `orders`
       GROUP BY `customer_id`    
       HAVING COUNT(id) > 1) as `morethanone`
On
    `customer`.`id`  = `morethanone`.`custmor_id`
ORDER BY
    `cust_id`

首先,您不需要将联接留在外部,因为它与内部联接之间的唯一区别将包括没有订单的客户,并且您在结果中不需要它们,因为它们的订单少于两个。

SELECT customers.id AS `cust_id`, orders.id AS `order_id`
FROM customers
     INNER JOIN orders ON `customers`.`id` = `orders`.`customer_id`
     INNER JOIN orders count_orders ON customers.id = count_orders.customer_id
GROUP BY count_orders.id, orders.id
HAVING count(count_orders.id) >= 2
ORDER BY `cust_id`

嘿,我猜我有点慢,但无论如何我都会发布我的答案。 它略有不同,但仍然有效。

SELECT `customers`.`id` AS `cust_id` , count( orders.id ) AS count_orders
FROM `customers`
JOIN `orders` ON `customers`.`id` = `orders`.`customer_id`
GROUP BY customers.id
HAVING count( orders.id ) >1
ORDER BY `cust_id`

如果您排除未订购的客户,则不需要LEFT JOIN,不是吗?

由于您需要结果集中的订单ID,因此需要先运行COUNT查询。

在SQL Server,2005 +中,CTE将执行计数查询的技巧,然后可以根据该计数查询生成所需的结果集:

WITH customerWithMoreThanOneOrder AS
(
    SELECT 
        `customers`.`id` AS `cust_id`
    FROM
        `customers`
    INNER JOIN `orders` ON
        `customers`.`id` = `orders`.`customer_id`
    GROUP BY 
        `customers`.`id`
    HAVING COUNT(0) > 1
)

SELECT 
    `customers`.`id` AS `cust_id`,
    `orders`.`id` AS `order_id`
FROM
    `customers`
INNER JOIN `orders` ON
    `customers`.`id` = `orders`.`customer_id`
WHERE `customers`.`id` IN (SELECT cust_id FROM customerWithMoreThanOneOrder)
ORDER BY
    `cust_id`

如果您使用的数据库不支持此结构,则只需将计数查询放在IN子查询的括号中,如下所示:

SELECT 
    `customers`.`id` AS `cust_id`,
    `orders`.`id` AS `order_id`
FROM
    `customers`
INNER JOIN `orders` ON
    `customers`.`id` = `orders`.`customer_id`
WHERE `customers`.`id` IN (SELECT 
                               `customers`.`id` AS `cust_id`
                           FROM
                               `customers`
                           INNER JOIN `orders` ON
                               `customers`.`id` = `orders`.`customer_id`
                           GROUP BY 
                               `customers`.`id`
                           HAVING COUNT(0) > 1)
ORDER BY
    `cust_id`

如果您有任何疑问,请告诉我

作为其他答案的替代方案,您可以使用IN子句。

SELECT 
    `customers`.`id` AS `cust_id`,
    `orders`.`id` AS `order_id`
FROM
    `customers`
LEFT JOIN `orders` ON
    `customers`.`id` = `orders`.`customer_id`
WHERE `customer_id` IN (SELECT `customer_id` FROM `orders` GROUP BY `customer_id` HAVING COUNT(*) > 1)
ORDER BY
    `cust_id`

暂无
暂无

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

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