Sql 从检索到的数据更改后添加未使用的表
我指的是,我正在使用它来学习SQLite。 此查询检索每个CustomerId的发票数量,如我所愿:Sql 从检索到的数据更改后添加未使用的表,sql,Sql,我指的是,我正在使用它来学习SQLite。 此查询检索每个CustomerId的发票数量,如我所愿: select i.customerid, count(i.invoiceid) from invoices as i group by i.customerid 返回: +------------+--------------------+ | CustomerId | count(i.invoiceid) | +------------+---------------
select i.customerid, count(i.invoiceid)
from invoices as i
group by i.customerid
返回:
+------------+--------------------+
| CustomerId | count(i.invoiceid) |
+------------+--------------------+
| 1 | 7 |
| 2 | 7 |
| 3 | 7 |
...
+------------+--------------------+
| CustomerId | count(i.invoiceid) |
+------------+--------------------+
| 1 | 413 |
| 2 | 413 |
| 3 | 413 |
...
但当我构建一个更复杂的查询时,我发现了一些我无法解释的东西:
select i.customerid, count(i.invoiceid)
from invoices as i, customers as c
group by i.customerid
返回:
+------------+--------------------+
| CustomerId | count(i.invoiceid) |
+------------+--------------------+
| 1 | 7 |
| 2 | 7 |
| 3 | 7 |
...
+------------+--------------------+
| CustomerId | count(i.invoiceid) |
+------------+--------------------+
| 1 | 413 |
| 2 | 413 |
| 3 | 413 |
...
结果是413=7*59,59是不同客户ID的数量。
这里我一定误解了一些基本的SQL行为,因为我希望在from子句中将客户添加为c不会有什么不同,因为我还没有使用它。有人能告诉我发生了什么吗?千万不要在FROM子句中使用逗号。仅使用正确、明确、标准、可读的联接语法
您的查询正在生成两个表中的行的笛卡尔乘积。然后,聚合计算笛卡尔乘积中每个客户的行数
你需要这样的东西:
select i.customerid, count(i.invoiceid)
from invoices i join
customers c
on i.customerid = c.customerid
group by i.customerid
您正在执行交叉联接,它是两个表的行的笛卡尔乘积。关于413值的起源,您是对的。
使用交叉联接时,如果表a有5行,表B有7行,则会产生5*7=35行的结果
在连接表时,您需要添加一个连接条件,该条件将过滤不相关的行。交叉连接很少是您想要的:
选择i.customerid、counti.invoiceid
从发票中取i,客户取c
其中i.customerid=c.id-连接条件
按i.customerid分组
但是推荐的join语法为显式无逗号:
选择i.customerid、counti.invoiceid
从我的发票上
以c显式联接方式联接客户
关于i.customerid=c.id-连接条件
按i.customerid分组
但默认情况下,这将执行一个内部联接,它要求发票表中的行至少与客户的1行匹配,反之亦然。
如果仍要显示发票为0的客户,则需要使用LEFT JOIN保留from子句中左表第一行的行,即使它们与右表不匹配:
选择i.customerid、counti.invoiceid
从我的发票上
左加入客户为c-保留没有发票的客户
在i.customerid=c.id-连接条件上,未更改
按i.customerid分组
您正在执行笛卡尔积,如下所示。您还可以添加一个WHERE子句来应用正确的连接条件OK,感谢大家让我意识到我正在进行交叉/笛卡尔连接。同时,我从本教程中得到了它,该教程建议使用这种语法进行交叉连接,谢谢!所以你写的和:选择i.customerid,counti.invoiceid,从i.customerid分组的发票中选择i.customerid,对吗?@acromarco。假设customerid在customers中没有重复,发票中的所有customerid都在customers中。哦,我从来没有意识到隐式连接条件在哪里,现在这比我的老师所展示的更有意义了!非常感谢您对“内部”和“左连接”的详细说明。@acromarco我教了几年MySQL,所以我找到了解释它的方法,我很高兴它有帮助:-如果您觉得我的答案有帮助,请点击向上投票按钮