所以我有两个销售表,预算表和实际表。
“预算”有两列:位置和销售。例如,
位置销售
24 $ 20000
36 $ 100300
40 $ 24700
总计$ 145000
“实际”具有三列:发票编号,位置和销售。例如,
发票位置销售
10000 36 $ 5000
10001 40 $ 6000
10002 99 $ 7000
等等
总计$ 110000
总而言之,“实际”在发票级别记录交易,而“预算”仅在地点级别记录(没有单独的发票)。
我正在尝试创建一个汇总表,该表并排列出按位置分组的实际销售额和预算销售额。实际列的总和应为110000美元,预算为145000美元。这是我的尝试(在pgAdmin / postgresql上):
SELECT actual.location, SUM(actual.sales) AS actual_sales, SUM(budget.sales) AS budget_sales
FROM actual LEFT JOIN budget
ON actual.location = budget.location
GROUP BY actual.location;
我之所以使用LEFT JOIN,是因为“实际”所在的位置没有“预算”所在的位置(例如,位置99)。
最后,我在actual_sales和budget_sales列上都得到了一些巨大的数字(百万美元),远远超过了实际总数(110000美元)或预算销售额(145,000美元)。
这是因为编写查询的方式基本上是要求SQL将“实际”中的每个发票都连接到“预算”中的每一行,因此重复了很多次?如果是这样,我应该怎么写呢?
谢谢!
答案 0 :(得分:0)
查询对我来说很好。但是,很难找出数字错误的原因。我的建议是,您将预算和实际支出按地点分别计入2个临时表中,然后使用LEFT JOIN将其汇总在一起。
答案 1 :(得分:0)
是的,您要为每个实际的销售行一次加入预算。但是,除非同一位置有多个预算行,否则您的“实际销售额”总和不应该更大。您应该检查一下,因为听起来不应该如此。
在这种情况下,您需要做的是首先在CTE或子查询中将实际销售额相加,然后再将结果加入预算。这样,每个位置只有一行。这样做是为了实际销售。如果确实有一个预算位置的行也有多个,则可能还需要以相同的方式对预算进行子查询。
Select Act.Location, Act.actual_sales, budget.sales as budget_sales
From
(
SELECT actual.location, SUM(actual.sales) AS actual_sales
FROM actual
GROUP BY actual.location
) Act
left join budget on Act.location = budget.location
答案 2 :(得分:0)
根据您的描述,您似乎在两个表中都有重复项。有多种方法可以解决此问题。这是使用union all
和group by
的一个:
select Location,
sum(actual_sales) as actual_sales,
sum(budget_sales) as budget_sales
from ((select a.location, a.sales as actual_sales, null as budget_sales
from actual a
) union all
(select b.location, null, b.sales
from budget b
)
) ab
group by location;
此结构保证与表无关,每个值仅计数一次。
答案 3 :(得分:0)
戈登的建议是好的,使用WITH
语句的替代方法是:
WITH aloc AS (
SELECT location, SUM(sales) FROM actual GROUP BY 1
), bloc AS (
SELECT location, SUM(sales) FROM budget GROUP BY 1
)
SELECT location, a.sum AS actual_sales, b.sum AS budget_sales
FROM aloc a LEFT JOIN bloc b USING (location)
这等效于:
SELECT location, a.sum AS actual_sales, b.sum AS budget_sales
FROM (SELECT location, SUM(sales) FROM actual GROUP BY 1) a LEFT JOIN
(SELECT location, SUM(sales) FROM budget GROUP BY 1) b USING (location)
但是我发现WITH
语句更具可读性。
子查询的目的是使表进入一种状态,在这种状态下,行意味着一些相关的内容,即aloc
在每个位置都包含一行,从而使联接评估您想要的状态。