簡體   English   中英

SQL查詢以按記錄的賬單號和產品代碼對記錄分組進行分區和求和

[英]Sql query to partition and sum the records grouping by their bill number and Product code

下面是兩個表,其中有母票號,例如1、4和8。這些母票號引用了none / NULL值。 它們由一個或多個子帳單號引用。 例如,父賬單1被子賬單2、3和6引用。

表B的“ bill no列還帶有帶有實際服務(ST值)和相關服務值(SV)的產品代碼。 SV是ST的額外費用。 同一ST可能出現在多個帳單編號中。 在這里,帳單號是唯一的。 例如,ST1在票據編號1和8中。同樣的SV可以引用相同或不同的ST。

SV1,SV2和SV3指的是與票據編號NO.1對應的ST1。 1和SV2和SV4指的是與票據2對應的ST2。

如何獲得低於預期的產出?

表A:

    |      bill no        |         ref      |          
    +----------------------------------------+
    |          1          |                  |
    |          2          |         1        |
    |          3          |         1        |
    |          4          |                  |
    |          5          |         4        |
    |          6          |         1        |
    |          7          |         4        |
    |          8          |                  |
    |          9          |         8        |

表B:

    |      bill no        |    Prod code     |     cost   |       
    +-----------------------------------------------------+
    |          1          |       ST1        |      10
    |          2          |       SV1        |      20
    |          3          |       SV2        |      30
    |          4          |       ST2        |      10
    |          5          |       SV2        |      20
    |          6          |       SV3        |      30
    |          7          |       SV4        |      40
    |          8          |       ST1        |      50
    |          9          |       SV1        |      10

預期產量:

    |      bill no        |    Prod code     | ST_cost    |     SV1    |     SV2    |     SV3     |          
    +---------------------------------------------------------------------------------------------+
    |          1          |       ST1        |      10    |  20        |   30       | 30          |
    |          4          |       ST2        |      10    |  20        |   40       |             |
    |          8          |       ST1        |      50    |  10        |            |             |

這是一個應該可以幫助您的腳本:

USE tempdb;
GO

DROP TABLE IF EXISTS dbo.TableA;

CREATE TABLE dbo.TableA
(
    BillNumber int NOT NULL PRIMARY KEY,
    Reference int NULL
);
GO

INSERT dbo.TableA (BillNumber, Reference)
SELECT *
FROM (VALUES (1,NULL),
             (2,1),    
             (3,1),
             (4,NULL),  
             (5,4),    
             (6,1),  
             (7,4),    
             (8,NULL),     
             (9,8)) AS a(BillNumber, Reference);
GO

DROP TABLE IF EXISTS dbo.TableB;

CREATE TABLE dbo.TableB
(
    BillNumber int NOT NULL PRIMARY KEY,
    ProductCode varchar(10) NOT NULL,
    Cost int NOT NULL
);
GO

INSERT dbo.TableB (BillNumber, ProductCode, Cost)
SELECT BillNumber, ProductCode, Cost
FROM (VALUES (1, 'ST1', 10),
             (2, 'SV1', 20),
             (3, 'SV2', 30),
             (4, 'ST2', 10),
             (5, 'SV2', 20),
             (6, 'SV3', 30),
             (7, 'SV4', 40),
             (8, 'ST1', 50),
             (9, 'SV1', 10)) AS b(BillNumber, ProductCode, Cost);
GO

WITH ParentBills
AS
(
    SELECT b.BillNumber, b.ProductCode, b.Cost AS STCost
    FROM dbo.TableB AS b
    INNER JOIN dbo.TableA AS a
    ON b.BillNumber = a.BillNumber
    WHERE a.Reference IS NULL 
),
SubBills
AS
(
    SELECT pb.BillNumber, pb.ProductCode, pb.STCost, 
           b.ProductCode AS ChildProduct, b.Cost AS ChildCost  
    FROM ParentBills AS pb
    INNER JOIN dbo.TableA AS a
    ON a.Reference = pb.BillNumber
    INNER JOIN dbo.TableB AS b
    ON b.BillNumber = a.BillNumber
)
SELECT sb.BillNumber, sb.ProductCode, sb.STCost,
       MAX(CASE WHEN sb.ChildProduct = 'SV1' THEN sb.ChildCost END) AS [SV1],
       MAX(CASE WHEN sb.ChildProduct = 'SV2' THEN sb.ChildCost END) AS [SV2],
       MAX(CASE WHEN sb.ChildProduct = 'SV3' THEN sb.ChildCost END) AS [SV3]
FROM SubBills AS sb
GROUP BY sb.BillNumber, sb.ProductCode, sb.STCost
ORDER BY sb.BillNumber;

您可以編寫一個函數,根據您的SV號創建查詢。 並使用“立即執行”執行查詢字符串,然后使用“ PIPE ROW”生成結果。 檢查此管道行示例

我不知道第二行的“ SV1”值來自哪里。

但是您的問題基本上是條件聚合:

with ab as (
      select a.*, b.productcode, b.cost,
             coalesce(a.reference, a.billnumber) as parent_billnumber 
      from a join
           b
           on b.billnumber = a.billnumber
     )
select parent_billnumber,
       max(case when reference is null then productcode end) as st,
       sum(case when reference is null then cost end) as st_cost,
       sum(case when productcode = 'SV1' then cost end) as sv1,
       sum(case when productcode = 'SV2' then cost end) as sv2,
       sum(case when productcode = 'SV3' then cost end) as sv3
from ab 
group by parent_billnumber
order by parent_billnumber;

是db <>小提琴。

請注意,此方法有效,因為您只有一個子級關系。 如果還有更多,則需要遞歸CTE。 我建議您提出一個問題,如果可能的話。

CTE實際上並沒有為查詢增加太多,因此您還可以編寫:

select coalesce(a.reference, a.billnumber) as parent_billnumber ,
       max(case when a.reference is null then productcode end) as st,
       sum(case when a.reference is null then b.cost end) as st_cost,
       sum(case when b.productcode = 'SV1' then b.cost end) as sv1,
       sum(case when b.productcode = 'SV2' then b.cost end) as sv2,
       sum(case when b.productcode = 'SV3' then b.cost end) as sv3
from a join
     b
     on b.billnumber = a.billnumber
group by coalesce(a.reference, a.billnumber) 
order by parent_billnumber;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM