我有这个 LEFT JOIN 吗?

发布于 2024-11-17 23:46:00 字数 1012 浏览 5 评论 0原文

我需要查找给定日期之后创建的尚未订购的客户总数。

我有两个表:

| customers           |    // There's more to this but this is all
+----+------+---------+    // you need to answer this question
| ID | Name | Created |
+----+------+---------+

| orders           |    // There's more to this but this is all
+----+-------------+    // you need to answer this question
| ID | customer_id |
+----+-------------+

我需要查找给定日期之后创建的尚未订购的客户总数。

这就是我所做的:

SELECT Count(*)
FROM customers
LEFT JOIN orders ON customers.ID = orders.customer_id
WHERE customers.Created > #arbitrary date#
AND orders.ID Is Null;

我确信这是正确的,但它似乎没有产生正确的结果。我的意思是我的老板正在查看结果并告诉我,根据经验,未订购的新客户注册数量远远超过此查询产生的数量。

那么我这样做对吗?如果是的话,我显然需要看看还有什么可能导致问题。谢谢。

编辑 1

下面的评论表明 orders.id 不可为空。情况可能是这样,但是如果我检查 orders.customer_id Is Null ,我会得到相同的结果。

编辑2

我不想让事情变得过于复杂,但如果您知道我是在 Access 数据库中执行此操作,因此我无法使用标准 SQL 允许的所有功能,那么它可能会很有用。 (我已经编辑了标签)

I need to find the total number of customers created after a given date that haven't yet ordered.

I have two tables:

| customers           |    // There's more to this but this is all
+----+------+---------+    // you need to answer this question
| ID | Name | Created |
+----+------+---------+

| orders           |    // There's more to this but this is all
+----+-------------+    // you need to answer this question
| ID | customer_id |
+----+-------------+

I need to find the total number of customers created after a given date that haven't yet ordered.

This is what I did:

SELECT Count(*)
FROM customers
LEFT JOIN orders ON customers.ID = orders.customer_id
WHERE customers.Created > #arbitrary date#
AND orders.ID Is Null;

I feel certain this is right, however it doesn't seem to be producing the right results. By that I mean my boss is looking at the results and telling me that from experience the numbers of new customer signups who aren't ordering are far more than what this query is producing.

So am I doing this right? If I am, I clearly need to look at what else could be causing the problem. Thanks.

EDIT 1

A comment below suggested that the orders.id is not nullable. This may be the case, however I get the same results if I check if orders.customer_id Is Null.

EDIT 2

I didn't want to overcomplicate things but it might be useful if you know that I'm doing this in an Access database so I can't use all the goodies that standard SQL allows. (I've edited the tags)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

逆光下的微笑 2024-11-24 23:46:00

你的老板必须告诉你他认为的“良好价值观”。

也许他曾经有一份报告与其他人一起过滤来统计这个客户。也许您必须检查订单表中某处的价格,如果价格= 0,则考虑不是真正的订单。

根据您提供给我们的信息,您的查询绝对正确,也许我会添加一些内容:

SELECT Count(DISTINCT customers.ID)
FROM customers
    LEFT JOIN orders 
        ON customers.ID = orders.customer_id
WHERE customers.Created > #arbitrary date#
AND orders.ID Is Null;

为了更容易维护和理解(查询应该会慢一点,但不会慢很多)

Your boss must tell you what he considered 'good values'.

Maybe he used to have a report with others filter to count this customer. Maybe you have to check a price somewhere in orders table, and consider not a real orders if price = 0.

With the information you give us, your query is absolutely right, maybe I will add something :

SELECT Count(DISTINCT customers.ID)
FROM customers
    LEFT JOIN orders 
        ON customers.ID = orders.customer_id
WHERE customers.Created > #arbitrary date#
AND orders.ID Is Null;

For easier maintenance and understanding (the query should be a little slower, but not that much)

万人眼中万个我 2024-11-24 23:46:00

我想知道它们是否是您的代码中等待发生的微妙错误。

该规范规定,“查找客户总数”。通过连接到 orders 表,您实际上依赖于连接。当然,对于没有订单的客户,您确实在统计客户。但是,对于有订单的客户,您将计算他们的订单。

我更喜欢一个反映客户计数的查询构造,以便我(或者实际上是更随意的用户)可以将反连接切换为半连接并获得预期结果(使用您的构造,他们将获得误导性的计数),

SELECT COUNT(*)
  FROM customers
 WHERE customers.Created > #specific date#
       AND NOT EXISTS (
                       SELECT *
                         FROM orders
                        WHERE orders.customer_id = customers.ID
                      );

例如对于已接受的答案,我提供“为了更容易维护和理解”(查询可能会慢一点,但希望不会慢很多)。

I'm wondering if their is a subtle bug-waiting-to-happen in your code.

The spec states, "find the total number of customers". By joining to the orders table you are actually counting on the join. Of course, in the case of customers with no orders you are indeed counting customers. However, for customers with orders you would be counting their orders.

I'd prefer a query construct that reflected the count on the customers so that I (or indeed a more casual user) could switch the antijoin to a semijoin and obtain the expected results (with your construct they would obtain a misleading count) e.g.

SELECT COUNT(*)
  FROM customers
 WHERE customers.Created > #specific date#
       AND NOT EXISTS (
                       SELECT *
                         FROM orders
                        WHERE orders.customer_id = customers.ID
                      );

As for the accepted answer, I offer this "For easier maintenance and understanding" (the query may be a little slower but hopefully not by much)."

﹏雨一样淡蓝的深情 2024-11-24 23:46:00

也许您的代码在某个地方允许为客户记录订单(但未完成)。
您可以统计仅订购金额为 0 的订单的客户。

SELECT COUNT(*)
FROM
  ( SELECT customers.id
    FROM customers
      INNER JOIN orders ON customers.ID = orders.customer_id
    WHERE customers.Created > #arbitrary date# 
    GROUP BY customers.id
    HAVING COUNT(IIF(orders.amount > 0, 1, NULL)) = 0  
  ) AS grp

Access 没有 CASE 语句,但有一个 IIF() 函数。

并且需要 INNER JOIN 而不是 JOIN

Perhaps somewhere your code allows orders to be recorded for customers (but not completed).
You can count customers that have ordered only orders with 0 amount.

SELECT COUNT(*)
FROM
  ( SELECT customers.id
    FROM customers
      INNER JOIN orders ON customers.ID = orders.customer_id
    WHERE customers.Created > #arbitrary date# 
    GROUP BY customers.id
    HAVING COUNT(IIF(orders.amount > 0, 1, NULL)) = 0  
  ) AS grp

Access has not CASE statement but it has an IIF() function.

And INNER JOIN is required instead of JOIN.

箹锭⒈辈孓 2024-11-24 23:46:00

不,这是不对的。

试试这个:

SELECT
SUM(CASE WHEN (SELECT COUNT(*) FROM orders WHERE customers.ID = orders.customer_id) = 0 
  THEN 1
  ELSE 0
END) 
FROM customers
WHERE customers.Created > #arbitrary date#

No this is not right.

Try this instead:

SELECT
SUM(CASE WHEN (SELECT COUNT(*) FROM orders WHERE customers.ID = orders.customer_id) = 0 
  THEN 1
  ELSE 0
END) 
FROM customers
WHERE customers.Created > #arbitrary date#
谎言月老 2024-11-24 23:46:00

看看这个网站,它解释了 sql 连接之间的所有差异

have a look at this website, it explains all the differences between the sql joins

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文