在 PostgreSQL 中连接多个 table,并计算连接的 table 行
Joining multiple tables in PostgreSQL, and counting joined table rows
我有三个 table。我正在尝试查询我的 PRICE_LIST
table,并计算每个价目表中有价格的 SKU 数量,以及分配给每个价目表的客户数量。
表格
我的PRICE_LIST
table:
price_list_id
price_number
name
这个table有41行。
我的SKU_PRICE
table:
sku_id
price_number
这个 table 有 1,132 行。
我的CUSTOMER
table:
customer_id
price_number
customer_type
is_active
这个 table 有 6,535 行,但我只想要活跃的 "E" 类型的客户,所以我想要的行数减少到 2,961。
查询
我的查询:
SELECT
pl.price_list_id,
pl.price_number,
pl.name,
count(sp.sku_id) "sku_count",
count(c.customer_id) "customer_count"
FROM price_list pl
LEFT JOIN sku_price sp ON (sp.price_number = pl.price_number)
LEFT JOIN customer c ON (c.price_number = pl.price_number)
WHERE c.customer_type = 'E' AND c.is_active = 'T'
GROUP BY pl.price_list_id, pl.price_number, pl.name;
问题
我遇到的问题是结果太疯狂了:
price_list_id | price_number | name | sku_count | customer_count
---------------+--------------+-------+-----------+----------------
31 | 4 | SF0 | 0 | 792
33 | 6 | SF2 | 30525 | 30525
2 | 2 | ASNP2 | 972 | 972
1 | 1 | ASNP1 | 1596 | 1596
34 | 7 | SF3 | 616 | 616
37 | 10 | SF6 | 0 | 51
32 | 5 | SF1 | 1144 | 1144
我得到的 SKU 计数和客户计数均为 30,525,这一事实告诉我连接正在做一些奇怪的事情。我也不明白为什么我没有得到没有产品也没有客户的价目表(而且有很多)。
如果我将 PRICE_LIST
加入到一个 table — SKU_PRICE
或 CUSTOMER
— 我会得到合理的结果。只有当我尝试同时执行这两项操作时,它才会崩溃。
如果有人能在正确的方向上推动我,我将不胜感激。
FWIW,我在 OS X 上使用 PostgreSQL 9.3.5。
如果我理解你的模式,你可以做类似的事情
select
pl.price_list_id,
pl.price_number,
pl.name,
count(distinct sp.sku_id) as "sku_count",
count(distinct c.customer_id) as "customer_count"
from price_list pl
left outer join sku_price as sp on sp.price_number = pl.price_number
left outer join customer as c on c.price_number = pl.price_number
where c.customer_type = 'E' and c.is_active = 'T'
group by pl.price_list_id, pl.price_number, pl.name;
但在性能方面我认为这样做会更好:
with cte_sku_price as (
select count(*) as cnt, price_number from sku_price group by price_number
), cte_customer as (
select count(*) as cnt, price_number
from customer
where customer_type = 'E' and is_active = 'T'
group by price_number
)
select
pl.price_list_id,
pl.price_number,
pl.name,
sp.cnt as "sku_count",
c.cnt as "customer_count"
from price_list pl
left outer join cte_customer as c on c.price_number = pl.price_number
left outer join cte_sku_price as sp on sp.price_number = pl.price_number
我有三个 table。我正在尝试查询我的 PRICE_LIST
table,并计算每个价目表中有价格的 SKU 数量,以及分配给每个价目表的客户数量。
表格
我的PRICE_LIST
table:
price_list_id
price_number
name
这个table有41行。
我的SKU_PRICE
table:
sku_id
price_number
这个 table 有 1,132 行。
我的CUSTOMER
table:
customer_id
price_number
customer_type
is_active
这个 table 有 6,535 行,但我只想要活跃的 "E" 类型的客户,所以我想要的行数减少到 2,961。
查询
我的查询:
SELECT
pl.price_list_id,
pl.price_number,
pl.name,
count(sp.sku_id) "sku_count",
count(c.customer_id) "customer_count"
FROM price_list pl
LEFT JOIN sku_price sp ON (sp.price_number = pl.price_number)
LEFT JOIN customer c ON (c.price_number = pl.price_number)
WHERE c.customer_type = 'E' AND c.is_active = 'T'
GROUP BY pl.price_list_id, pl.price_number, pl.name;
问题
我遇到的问题是结果太疯狂了:
price_list_id | price_number | name | sku_count | customer_count
---------------+--------------+-------+-----------+----------------
31 | 4 | SF0 | 0 | 792
33 | 6 | SF2 | 30525 | 30525
2 | 2 | ASNP2 | 972 | 972
1 | 1 | ASNP1 | 1596 | 1596
34 | 7 | SF3 | 616 | 616
37 | 10 | SF6 | 0 | 51
32 | 5 | SF1 | 1144 | 1144
我得到的 SKU 计数和客户计数均为 30,525,这一事实告诉我连接正在做一些奇怪的事情。我也不明白为什么我没有得到没有产品也没有客户的价目表(而且有很多)。
如果我将 PRICE_LIST
加入到一个 table — SKU_PRICE
或 CUSTOMER
— 我会得到合理的结果。只有当我尝试同时执行这两项操作时,它才会崩溃。
如果有人能在正确的方向上推动我,我将不胜感激。
FWIW,我在 OS X 上使用 PostgreSQL 9.3.5。
如果我理解你的模式,你可以做类似的事情
select
pl.price_list_id,
pl.price_number,
pl.name,
count(distinct sp.sku_id) as "sku_count",
count(distinct c.customer_id) as "customer_count"
from price_list pl
left outer join sku_price as sp on sp.price_number = pl.price_number
left outer join customer as c on c.price_number = pl.price_number
where c.customer_type = 'E' and c.is_active = 'T'
group by pl.price_list_id, pl.price_number, pl.name;
但在性能方面我认为这样做会更好:
with cte_sku_price as (
select count(*) as cnt, price_number from sku_price group by price_number
), cte_customer as (
select count(*) as cnt, price_number
from customer
where customer_type = 'E' and is_active = 'T'
group by price_number
)
select
pl.price_list_id,
pl.price_number,
pl.name,
sp.cnt as "sku_count",
c.cnt as "customer_count"
from price_list pl
left outer join cte_customer as c on c.price_number = pl.price_number
left outer join cte_sku_price as sp on sp.price_number = pl.price_number