[英]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.