Mysql 如何按计数限制SQL左联接查询的结果集
我希望使用左连接查询从两个具有一对多关系的表中获取一些结果,但根据“子项”的计数限制结果集。我有两张表格,结构如下:Mysql 如何按计数限制SQL左联接查询的结果集,mysql,sql,join,Mysql,Sql,Join,我希望使用左连接查询从两个具有一对多关系的表中获取一些结果,但根据“子项”的计数限制结果集。我有两张表格,结构如下: customers id name ... 1 "bob" ... 2 "jill" ... orders id customer_id ... 100 1 ... 101 2 ... 102 1 ... (表中的其余数据与此查询无关。) 我
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
我从一个基本的左连接开始,将订单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`
谢谢大家。一种方法是创建一个内联视图,让拥有多个订单的客户和内部用户加入该视图。如果您不喜欢加入,也可以在或存在中执行
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`
如果您排除了尚未订购的客户,则不需要左连接,不是吗 由于您希望在结果集中显示订单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`
如果您使用的数据库不支持此结构,则只需将count查询放在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`
如果你有任何问题,请告诉我。嘿,我想我有点慢,但我还是会发布我的答案。虽然略有不同,但仍然有效
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`
作为其他答案的替代,您可以使用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`
在我回答之前先把我的答案记下来!谢谢这似乎给了我想要的结果集。很高兴我能提供帮助,但你应该注意到,Marlin Pierce是正确的,
左连接实际上没有任何作用,因为我们已经消除了任何没有订单的客户。这是针对MySQL的,所以我无法评论第一个建议是否有效。然而,第二个建议似乎将mysqld进程发送到一个无限循环中。对我来说,这个查询似乎是合乎逻辑的,所以它可能是MySQL本身的问题。他们发布的版本最近越来越多…这就快到了。。。似乎给出了正确的结果集,而您的结果集给出了相同的行数;但是,每个客户ID下的订单ID都是重复的。例如,它给出的不是“1100;1102”,而是“1100;1100”(扩展我问题中的示例)。SQL确实需要尝试和调整,所以这就是即兴SQL答案的问题。+1有趣的解决方案。我从未见过有人通过创建一个允许您按同一字段计数和分组的方法来解决这个问题。在FROM子句中多次加入表是一种常见的SQL技术。@MarlinPierce-hmm加入多个yes。这样做是为了创建笛卡尔积,这样您就可以分组和计数。。。我不记得看到过(这个问题的变体出现了很多)