英文:
Snowflake SQL - Sum with one-to-many joins
问题
我试图编写一个查询,以显示订单上的项目何时被输入或“键入”,以及该项目何时被开具发票。在某些情况下,一个项目可能会有多个开票日期。由于存在多个开票日期,我得到了SALES_ORDER_ITEM_QUANTITY和KEYED_GSAR字段的重复结果。
以下是我尝试使用的查询。它已经针对一个订单进行了筛选,以说明我遇到的问题。
vwith sales_orders as (
select
O.SALES_ORDER_ITEM_CREATE_DATE,
O.SALES_ORDER_ID,
O.MATERIAL_ID,
O.SALES_ORDER_ITEM_ID,
sum(distinct o.gsar) as keyed_sales,
sum(distinct o.sales_order_item_quantity) as SALES_ORDER_ITEM_QTY
from EDP.RPT_SALES.SALES_ORDERS O
where O.FISCAL_YR_ID IN (2022,2023)
AND O.WW_CHANNEL IN ('RENOVATION','INSTALLATION')
and o.sales_order_id = '0306231843'
GROUP BY
O.SALES_ORDER_ITEM_CREATE_DATE,
O.SALES_ORDER_ID,
O.MATERIAL_ID,
O.SALES_ORDER_ITEM_ID
)
,billing as (
select
B.BILLING_DOC_DATE,
B.SALES_DOC_ID,
B.MATERIAL_ID,
B.SALES_DOC_ITEM_ID,
sum(B.BILL_QTY) as BILL_QTY,
sum(B.GSAR) as GSAR
from EDP.RPT_SALES.BILLING B
where b.fiscal_yr_id IN (2022,2023)
AND b.WW_CHANNEL IN ('RENOVATION','INSTALLATION')
group by
B.BILLING_DOC_DATE,
B.SALES_DOC_ID,
B.MATERIAL_ID,
B.SALES_DOC_ITEM_ID
)
SELECT
O.SALES_ORDER_ITEM_CREATE_DATE,
LTRIM(O.SALES_ORDER_ID,'0') SALES_ORDER_ID,
LTRIM(O.MATERIAL_ID,'0') MATERIAL_ID,
O.SALES_ORDER_ITEM_ID,
O.SALES_ORDER_ITEM_QTY,
KEYED_SALES,
B.BILLING_DOC_DATE,
B.BILL_QTY,
B.GSAR BILLED_SALES
FROM sales_orders O
LEFT JOIN billing B ON O.SALES_ORDER_ID = B.SALES_DOC_ID AND O.MATERIAL_ID = B.MATERIAL_ID AND O.SALES_ORDER_ITEM_ID = B.SALES_DOC_ITEM_ID
这个订单上有一个材料,编号为128470。订购数量为40,价值$7,783.60。这个材料在4个不同的日期开具了发票,如BILLING_DOC_DATE列所示。SALES_ORDER_ITEM_QUANTITY和KEYED_SALES的值被重复出现了4次。以下是我得到的结果:
SALES_ORDER_ITEM_CREATE_DATE | SALES_ORDER_ID | MATERIAL_ID | SALES_ORDER_ITEM_ID | SALES_ORDER_ITEM_QTY | KEYED_SALES | BILLING_DOC_DATE | BILL_QTY | BILLED_SALES |
---|---|---|---|---|---|---|---|---|
2023-03-31 | 306231843 | 128470 | 20 | 40 | 7783.60 | 2023-03-31 | 31 | 6032.29 |
2023-03-31 | 306231843 | 128470 | 20 | 40 | 7783.60 | 2023-03-23 | 5 | 972.95 |
2023-03-31 | 306231843 | 128470 | 20 | 40 | 7783.60 | 2023-04-05 | 3 | 58.77 |
2023-03-31 | 306231843 | 128470 | 20 | 40 | 7783.60 | 2023-03-29 | 1 | 194.59 |
以下是期望的结果:
SALES_ORDER_ITEM_CREATE_DATE | SALES_ORDER_ID | MATERIAL_ID | SALES_ORDER_ITEM_ID | SALES_ORDER_ITEM_QTY | KEYED_SALES | BILLING_DOC_DATE | BILL_QTY | BILLED_SALES |
---|---|---|---|---|---|---|---|---|
2023-03-31 | 306231843 | 128470 | 20 | 40 | 7783.60 | 2023-03-31 | 31 | 6032.29 |
2023-03-31 | 306231843 | 128470 | 20 | 0 | 0 | 2023-03-23 | 5 | 972.95 |
2023-03-31 | 306231843 | 128470 | 20 | 0 | 0 | 2023-04-05 | 3 | 58.77 |
2023-03-31 | 306231843 | 128470 | 20 | 0 | 0 | 2023-03-29 | 1 | 194.59 |
英文:
I am trying to write a query that shows when an item on an order was entered or "keyed" in, and then when that item was billed. In certain cases, one item will have multiple billing dates. Because of there being multiple billing dates, I am getting duplicate results of the SALES_ORDER_ITEM_QUANTITY AND KEYED_GSAR fields.
Below is the query that I am trying to use. It is filtered on one order to illustrate the problem I am having.
vwith sales_orders as (
select
O.SALES_ORDER_ITEM_CREATE_DATE,
O.SALES_ORDER_ID,
O.MATERIAL_ID,
O.SALES_ORDER_ITEM_ID,
sum(distinct o.gsar) as keyed_sales,
sum(distinct o.sales_order_item_quantity) as SALES_ORDER_ITEM_QTY
from EDP.RPT_SALES.SALES_ORDERS O
where O.FISCAL_YR_ID IN (2022,2023)
AND O.WW_CHANNEL IN ('RENOVATION','INSTALLATION')
and o.sales_order_id = '0306231843'
GROUP BY
O.SALES_ORDER_ITEM_CREATE_DATE,
O.SALES_ORDER_ID,
O.MATERIAL_ID,
O.SALES_ORDER_ITEM_ID
)
,billing as (
select
B.BILLING_DOC_DATE,
B.SALES_DOC_ID,
B.MATERIAL_ID,
B.SALES_DOC_ITEM_ID,
sum(B.BILL_QTY) as BILL_QTY,
sum(B.GSAR) as GSAR
from EDP.RPT_SALES.BILLING B
where b.fiscal_yr_id IN (2022,2023)
AND b.WW_CHANNEL IN ('RENOVATION','INSTALLATION')
group by
B.BILLING_DOC_DATE,
B.SALES_DOC_ID,
B.MATERIAL_ID,
B.SALES_DOC_ITEM_ID
)
SELECT
O.SALES_ORDER_ITEM_CREATE_DATE,
LTRIM(O.SALES_ORDER_ID,'0') SALES_ORDER_ID,
LTRIM(O.MATERIAL_ID,'0') MATERIAL_ID,
O.SALES_ORDER_ITEM_ID,
O.SALES_ORDER_ITEM_QTY,
KEYED_SALES,
B.BILLING_DOC_DATE,
B.BILL_QTY,
B.GSAR BILLED_SALES
FROM sales_orders O
LEFT JOIN billing B ON O.SALES_ORDER_ID = B.SALES_DOC_ID AND O.MATERIAL_ID = B.MATERIAL_ID AND O.SALES_ORDER_ITEM_ID = B.SALES_DOC_ITEM_ID
This order has one material on it, 128470. There was a quantity of 40 ordered for a value of $7,783.60. This material was billed on 4 separate dates, as seen in the BILLING_DOC_DATE column. The SALES_ORDER_ITEM_QUANTITY and KEYED_SALES values are getting duplicated 4 times. Below are the results I am getting:
SALES_ORDER_ITEM_CREATE_DATE | SALES_ORDER_ID | MATERIAL_ID | SALES_ORDER_ITEM_ID | SALES_ORDER_ITEM_QTY | KEYED_SALES | BILLING_DOC_DATE | BILL_QTY | BILLED_SALES |
---|---|---|---|---|---|---|---|---|
2023-03-31 | 306231843 | 128470 | 20 | 40 | 7783.60 | 2023-03-31 | 31 | 6032.29 |
2023-03-31 | 306231843 | 128470 | 20 | 40 | 7783.60 | 2023-03-23 | 5 | 972.95 |
2023-03-31 | 306231843 | 128470 | 20 | 40 | 7783.60 | 2023-04-05 | 3 | 58.77 |
2023-03-31 | 306231843 | 128470 | 20 | 40 | 7783.60 | 2023-03-29 | 1 | 194.59 |
Below are the desired results
SALES_ORDER_ITEM_CREATE_DATE | SALES_ORDER_ID | MATERIAL_ID | SALES_ORDER_ITEM_ID | SALES_ORDER_ITEM_QTY | KEYED_SALES | BILLING_DOC_DATE | BILL_QTY | BILLED_SALES |
---|---|---|---|---|---|---|---|---|
2023-03-31 | 306231843 | 128470 | 20 | 40 | 7783.60 | 2023-03-31 | 31 | 6032.29 |
2023-03-31 | 306231843 | 128470 | 20 | 0 | 0 | 2023-03-23 | 5 | 972.95 |
2023-03-31 | 306231843 | 128470 | 20 | 0 | 0 | 2023-04-05 | 3 | 58.77 |
2023-03-31 | 306231843 | 128470 | 20 | 0 | 0 | 2023-03-29 | 1 | 194.59 |
答案1
得分: 0
我建议在计费数据中添加一个“行号”,以区分要输出销售数据的行,以避免重复。同时,我建议您除非有合法的理由要省略一些数据,否则不要使用 sum(distinct ...)
。考虑到您正在从单个表中汇总销售信息,似乎非常不可能需要使用 sum(distinct ...)
。即,如果一个订单有2个数量为20的条目,那么总订单数量应该是40,不是吗?
vwith sales_orders AS (
SELECT O.SALES_ORDER_ITEM_CREATE_DATE
, O.SALES_ORDER_ID
, O.MATERIAL_ID
, O.SALES_ORDER_ITEM_ID
, sum(o.gsar) AS keyed_sales
, sum(o.sales_order_item_quantity) AS SALES_ORDER_ITEM_QTY
FROM EDP.RPT_SALES.SALES_ORDERS O
WHERE O.FISCAL_YR_ID IN (2022, 2023) AND O.WW_CHANNEL IN ('RENOVATION', 'INSTALLATION') AND o.sales_order_id = '0306231843'
GROUP BY O.SALES_ORDER_ITEM_CREATE_DATE
, O.SALES_ORDER_ID
, O.MATERIAL_ID
, O.SALES_ORDER_ITEM_ID
)
, billing AS (
SELECT B.BILLING_DOC_DATE
, B.SALES_DOC_ID
, B.MATERIAL_ID
, B.SALES_DOC_ITEM_ID
, sum(B.BILL_QTY) AS BILL_QTY
, sum(B.GSAR) AS GSAR
, row_number() OVER (
PARTITION BY B.SALES_DOC_ID
, B.MATERIAL_ID
, B.SALES_DOC_ITEM_ID ORDER BY B.BILLING_DOC_DATE
) AS rn
FROM EDP.RPT_SALES.BILLING B
WHERE b.fiscal_yr_id IN (2022, 2023) AND b.WW_CHANNEL IN ('RENOVATION', 'INSTALLATION')
GROUP BY B.BILLING_DOC_DATE
, B.SALES_DOC_ID
, B.MATERIAL_ID
, B.SALES_DOC_ITEM_ID
)
SELECT O.SALES_ORDER_ITEM_CREATE_DATE
, LTRIM(O.SALES_ORDER_ID, '0') SALES_ORDER_ID
, LTRIM(O.MATERIAL_ID, '0') MATERIAL_ID
, O.SALES_ORDER_ITEM_ID
, CASE WHEN b.rn = 1 THEN O.SALES_ORDER_ITEM_QTY ELSE 0 END AS SALES_ORDER_ITEM_QTY
, CASE WHEN b.rn = 1 THEN O.KEYED_SALES ELSE 0 END AS KEYED_SALES
, B.BILLING_DOC_DATE
, B.BILL_QTY
, B.GSAR BILLED_SALES
FROM sales_orders O
LEFT JOIN billing B ON O.SALES_ORDER_ID = B.SALES_DOC_ID AND O.MATERIAL_ID = B.MATERIAL_ID AND O.SALES_ORDER_ITEM_ID = B.SALES_DOC_ITEM_ID
英文:
I suggest you need a "row number" in the billing data to distinguish which row to output the sales data so that you can avoid repeats. Whilst here, I also suggest you don't use sum(distinct ...)
unless you have a legitimate reason to omit some data. Given you are summing sales info from a single table it seems very unlikely that you need sum(distinct ...)
. i.e. If an order had 2 entries of qty = 20 then the total order qty = 40 isn't it?
vwith sales_orders AS (
SELECT O.SALES_ORDER_ITEM_CREATE_DATE
, O.SALES_ORDER_ID
, O.MATERIAL_ID
, O.SALES_ORDER_ITEM_ID
, sum(o.gsar) AS keyed_sales
, sum(o.sales_order_item_quantity) AS SALES_ORDER_ITEM_QTY
FROM EDP.RPT_SALES.SALES_ORDERS O
WHERE O.FISCAL_YR_ID IN (2022, 2023) AND O.WW_CHANNEL IN ('RENOVATION', 'INSTALLATION') AND o.sales_order_id = '0306231843'
GROUP BY O.SALES_ORDER_ITEM_CREATE_DATE
, O.SALES_ORDER_ID
, O.MATERIAL_ID
, O.SALES_ORDER_ITEM_ID
)
, billing AS (
SELECT B.BILLING_DOC_DATE
, B.SALES_DOC_ID
, B.MATERIAL_ID
, B.SALES_DOC_ITEM_ID
, sum(B.BILL_QTY) AS BILL_QTY
, sum(B.GSAR) AS GSAR
, row_number() OVER (
PARTITION BY B.SALES_DOC_ID
, B.MATERIAL_ID
, B.SALES_DOC_ITEM_ID ORDER BY B.BILLING_DOC_DATE
) AS rn
FROM EDP.RPT_SALES.BILLING B
WHERE b.fiscal_yr_id IN (2022, 2023) AND b.WW_CHANNEL IN ('RENOVATION', 'INSTALLATION')
GROUP BY B.BILLING_DOC_DATE
, B.SALES_DOC_ID
, B.MATERIAL_ID
, B.SALES_DOC_ITEM_ID
)
SELECT O.SALES_ORDER_ITEM_CREATE_DATE
, LTRIM(O.SALES_ORDER_ID, '0') SALES_ORDER_ID
, LTRIM(O.MATERIAL_ID, '0') MATERIAL_ID
, O.SALES_ORDER_ITEM_ID
, CASE WHEN b.rn = 1 THEN O.SALES_ORDER_ITEM_QTY ELSE 0 END AS SALES_ORDER_ITEM_QTY
, CASE WHEN b.rn = 1 THEN O.KEYED_SALES ELSE 0 END AS KEYED_SALES
, B.BILLING_DOC_DATE
, B.BILL_QTY
, B.GSAR BILLED_SALES
FROM sales_orders O
LEFT JOIN billing B ON O.SALES_ORDER_ID = B.SALES_DOC_ID AND O.MATERIAL_ID = B.MATERIAL_ID AND O.SALES_ORDER_ITEM_ID = B.SALES_DOC_ITEM_ID
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论