postgresql 如果RIGHT表中没有条目,则获取计数0

llmtgqce  于 2023-01-17  发布在  PostgreSQL
关注(0)|答案(4)|浏览(152)

表"网站":
| 网站ID|网站名称|
| - ------|- ------|
| 1个|网站_a|
| 第二章|网站_b|
| 三个|网站_c|
| 四个|网站_d|
| 五个|网站_e|
表"夹具":
| 夹具标识|网站_id|夹具_详细信息|
| - ------|- ------|- ------|
| 1个|1个|甲对乙|
| 第二章|1个|c与d|
| 三个|第二章|e与f|
| 四个|第二章|g与h|
| 五个|四个|i对j|

    • 预期产出**:

| 网站ID|网站名称|总行数|
| - ------|- ------|- ------|
| 1个|网站_a|第二章|
| 第二章|网站_b|第二章|
| 三个|网站_c|无|
| 四个|网站_d|1个|
| 五个|网站_e|无|
如果夹具表中没有条目,我希望得到0。
目前我有以下SQL:-

Select fx.website_id, ws.website_name, Count (*) as TotalRows 
FROM fixtures fx
LEFT JOIN websites ws on ws.website_id = fx.website_id
WHERE date_of_entry = '16-01-2023'
GROUP BY
  fx.website_id, ws.website_name
;

但是,当没有条目时,它不会返回0值。
我如何更改我的SQL来反映这一点?
提前感谢您的帮助和时间

n9vozmp4

n9vozmp41#

尝试以下语句:

SELECT ws.website_id, ws.website_name, COUNT(fx.id) AS number_of_fixtures
FROM websites ws
LEFT JOIN fixtures fx ON fx.website_id = ws.website_id
WHERE TRUE -- or whatever condition you want but I do not know where to take date_of_entry from
GROUP BY ws.website_id

以表达式作为参数的COUNT对每行计算此表达式,如果该行的计算结果为NULL,则不计算该行。
如果您想坚持您的连接顺序,则需要fixtures RIGHT JOIN websites

uajslkp6

uajslkp62#

问题是你在计算*即行数与表格无关;因此当fixtures表中只有一条记录时,返回的值为1,可以通过使用count(ws.website_id)计算websites表中的行数来解决这个问题;因为在存在来自该表的结果的情况下,该字段将返回非空值并因此被计数;而在没有记录的情况下,该字段将为空,因此不计数。

Select fx.website_id, ws.website_name, Count (ws.website_id) as TotalRows 
FROM fixtures fx
LEFT JOIN websites ws on ws.website_id = fx.website_id
WHERE fx.date_of_entry = '16-01-2023'
GROUP BY
  fx.website_id, ws.website_name
;
igsr9ssn

igsr9ssn3#

你已经很接近了,你不能得到那些0计数的记录的原因是因为如果没有与特定网站相关的固定装置记录,date_of_entry将为NULLWHERE date_of_entry = '16-01-2023'将过滤掉所有这些记录。因此,解决方案要么将其放入LEFT JOIN条件中,要么在where子句中添加额外的条件。另一个核心问题是你是按网站相关数据分组计数,你必须选择从网站或右连接到夹具,以保持所有网站记录显示在结果中。
溶液A

Select ws.id AS website_id, ws.website_name, Count (*) as TotalRows 
FROM websites ws 
LEFT JOIN fixtures fx on ws.website_id = fx.website_id AND date_of_entry = '16-01-2023'
GROUP BY
  ws.id, ws.website_name
;

溶液B

Select ws.id AS website_id, ws.website_name, Count (*) as TotalRows 
FROM websites ws 
LEFT JOIN fixtures fx on ws.website_id = fx.website_id
WHERE date_of_entry IS NULL OR date_of_entry = '16-01-2023'
GROUP BY
  ws.id, ws.website_name
;
7rfyedvj

7rfyedvj4#

您的查询中存在两个问题:

  • 在你的LEFT JOIN中表格的位置是错误的:把fixture放在第一个表中可以确保所有的fixture都显示出来,但是你主要希望每个网站都有一行(因此website表应该显示在第一个-websites wb LEFT JOIN fixtures fx
  • COUNT应该应用于左表的一个字段,因为否则,如果每个字段中都有NULL值的行,它将计数,但只要LEFT JOIN确保检索右表的所有值,就不会发生这种情况

以下解决方案可能会解决您的所有问题:

SELECT ws.website_id, ws.website_name, COUNT(fx.fixture_id) AS cnt
FROM websites ws
LEFT JOIN fixtures fx 
       ON ws.website_id = fx.website_id
WHERE date_of_entry = '16-01-2023'
GROUP BY ws.website_id, ws.website_name

检查here演示。

注意:“date_of_entry”不会出现在小提琴中,因为它也不会出现在您的样本数据中。

相关问题