SQL左外连接带有WHERE条件。

huangapple go评论69阅读模式
英文:

SQL left outer join with where condition

问题

第一个查询返回的计数值是 12332

但是在第二个查询中,返回的计数值是 1224

第二个查询中计数不同的原因是因为在连接条件中添加了一个额外的条件 to_char(od.order_date::timestamp, 'yyyy-MM') = '2014-01'。这个条件限制了连接的结果集,只包括符合条件的行,而不是保留左表中的所有行。所以计数不同的原因在于第二个查询只计算了满足额外条件的行数。左外连接确实会保留左表中的所有行,但在计数时,只考虑了符合连接条件和额外条件的行。

您的理解基本正确,左外连接会保留左表中的所有行,但计数仍然受到连接条件和额外条件的限制。所以,在第二个查询中,只有满足 to_char(od.order_date::timestamp, 'yyyy-MM') = '2014-01' 条件的行被计数,因此计数值较小。

英文:

I am new to SQL and learning joins.

Please consider the two queries below:

When I run the first query below:

select count(*)
from products p 
left outer join order_details_v od 
on p.product_id = od.order_item_product_id

Returned count value is 12332

But when I am this second query:

select count(*)
from products p 
	left outer join order_details_v od 
	on p.product_id = od.order_item_product_id
	and to_char(od.order_date::timestamp, 'yyyy-MM') = '2014-01'

Returned count value is 1224

Why is the count is different in the second query? I understand that we have added an additional condition in the join, but since it is a left outer join, it should keep all the rows of the left table and therefore count should be same. Where am I wrong?

答案1

得分: 0

计数已减少到1224,因为还有一个额外的筛选器 "and to_char(od.order_date::timestamp, 'yyyy-MM') = '2014-01'"。
对于这个order_date列的筛选器仅考虑了连接结果集中的特定行,并为您提供了不同的计数。
希望这有所帮助。

英文:

The count has been reduced to 1224 as there is also an additional filter "and to_char(od.order_date::timestamp, 'yyyy-MM') = '2014-01'"
Filter of this order_date column has accounted only those specific rows out of the join result set and gave you different number count.
Hope this helps.

答案2

得分: 0

如果你将查询从Count()更改为,你可以轻松地查看发生了什么。

使用LEFT OUTER JOIN并在订单日期上添加额外的过滤器将始终返回每个产品的至少一行。此外,每个在2014-01日有订单的产品可能会有多行订单。这将扩大报告产品所需的行数。

随着你对SQL的了解越来越多,探索更多SQL命令来检查结果。如果你在查询中添加Select COUNT(DISTINCT p.product_id),你会注意到计数保持不变。

你的SQL返回COUNT(产品,其中产品订单日期为null) + SUM(订单日期为2014-01的产品详细信息计数)

初学者通常没有意识到的另一个要点是,如果你将限制条件添加到where子句而不是on子句,比如Select ... from ... Where订单日期为'2014-01',你的结果将表现得像一个内连接,只有那些在当天被订购的产品会被返回。在连接右侧的订单日期中的空值在外连接之后为null,但在where子句中,null不等于订单日期为'2014-01'。因此,所有这些记录都被删除而不是报告。

祝你在学习这门语言时好运。

英文:

If you change the query from Count(*) to * you can easily inspect what is occurring.

Using a LEFT OUTER JOIN with the additional filter on the order date will always return at least one row for each of the products. Additionally, each product that had orders on 2014-01 will likely have multiple lines for an order. That will expand the count of rows needed to report the product.

As you learn more about SQL, explore more SQL commands to examine results. If you add Select COUNT (DISTINCT p.product_id) to your query you'll notice that the count remains the same.

Your SQL returns the COUNT(products where the product order date is null) + SUM(product detail counts where the order day is 2014-01)

One additional point beginners don't realize is if you add the restriction to a where clause instead of the on clause such as Select ... from ... Where order day is '2014-01' your result will behave like an inner join and only products that have been ordered on the day will be returned. The data with null values in the order date of the right side of the join were null after the outer join, but in the where clause null does not equal order day is '2014-01. So all of those records are removed instead of reported.

Good luck as you learn the language.

huangapple
  • 本文由 发表于 2023年6月28日 23:57:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/76574868.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定