簡體   English   中英

SQL自我參照表中的主要類別分組

[英]SQL Group by main category in self-referenced table

我需要獲取按主要類別和Seller分組的總銷售額列表。 請注意,主要類別上可能會有銷售(這是我目前可以想到的最好的例子)。

源表

+--------------------------------------+
|ID   |Name        |Seller|Qty|ParentID|
+--------------------------------------+
|10   |Egg         |John  |5  |NULL    |
|10   |Egg         |Anna  |2  |NULL    |
|10-01|Egg - Small |John  |3  |10      |
|10-01|Egg - Small |Anna  |4  |10      |
|10-02|Egg - Medium|John  |2  |10      |
|10-02|Egg - Medium|Bob   |11 |10      |
|10-03|Egg - Large |Anna  |7  |10      |
+--------------------------------------+

所需的輸出

+------------------+
|ID|Name|Seller|Qty|
+------------------+
|10|Egg |John  |10 | <- SUM of all sales John has made for any type of egg
|10|Egg |Anna  |13 |
|10|Egg |Bob   |11 |
+------------------+

我與這個查詢很接近,但是如果有人沒有在主要類別上進行銷售,當我使用MIN(Name)時,他們將得到錯誤的Name

當前查詢

SELECT 
    SUBSTRING(t1.ID, 1, 2) AS 'ID',
    MIN(t1.Name) AS 'Name', 
    t1.Seller, 
    SUM(t1.Qty) AS 'Qty'
FROM EggTest t1
GROUP BY 
    SUBSTRING(t1.ID, 1, 2),
    t1.Seller

電流輸出

+--------------------------+
|ID|Name        |Seller|Qty|
+--------------------------+
|10|Egg         |Anna  |13 |
|10|Egg - Medium|Bob   |11 | <- Bob has not made sales on the main category
|10|Egg         |John  |10 |
+--------------------------+

編輯:看到多個答案已經建議SUBSTRING(Name, 1, 3)對我不起作用。 Name並不總是以“ Egg”開頭。

更新:

現在嘗試此查詢:

WITH report AS(
  SELECT 
    ID = CASE WHEN s.ParentID IS NOT NULL THEN s.ParentID ELSE s.ID END,
    Name = CASE WHEN s.ParentID IS NOT NULL THEN p.Name ELSE s.Name END,
    s.Seller,
    s.Qty
  FROM EggTest s
  LEFT JOIN EggTest p ON p.ID = s.ParentID
)

SELECT ID, Name, Seller, SUM(Qty) AS 'Total'
FROM report
GROUP BY ID, Name, Seller;

但是我得到這個奇怪的結果:

+--------------------+
|ID|Name|Seller|Total|
+--------------------+
|10|Egg |Anna  |24   | <- Wrong (Should be 13)
|10|Egg |Bob   |22   | <- Wrong (Should be 11)
|10|Egg |John  |15   | <- Correct(!!)
+--------------------+

report -table中,我得到了一些重復項:

+------------------+
|ID|Name|Seller|Qty|
+------------------+
|10|Egg |John  |5  |
|10|Egg |Anna  |2  |
|10|Egg |John  |3  |
|10|Egg |John  |3  |
|10|Egg |Anna  |4  |
|10|Egg |Anna  |4  |
|10|Egg |John  |2  |
|10|Egg |John  |2  |
|10|Egg |Anna  |7  |
|10|Egg |Anna  |7  |
|10|Egg |Bob   |11 |
|10|Egg |Bob   |11 |
+------------------+

我將源表名稱視為[ Sales ]

您可以使用以下內容

with report as(
   select ID = case when s.ParentID is not null then s.ParentID else s.ID end,
          Name= case when s.ParentID is not null then p.Name else s.Name end,
          s.Seller,
          s.Qty
   from Sales s
   left join Sales p on p.ID = s.ParentID and p.Seller = s.Seller
)
select ID,Name,Seller,sum(Qty) as Qty
from report
group by ID,Name,Seller

這是使用Distinct演示

這是一個通過Seller in the left join包含Seller in the left join演示 ,這將為您提供賣方Bob的項目名稱為NULL ,如果您具有正確的數據完整性,這意味着應該使用單獨的表來顯示條目和類別,則左側聯接應該可以工作

回復您的最后評論,這里是一個演示如何使您的數據清晰

希望這個能對您有所幫助

試試這個查詢。 如果您需要解釋,請詢問:)但這是相當簡單的查詢:)

SELECT MAX(SUBSTRING(ID, 1, 2)) AS ID, 
       SUBSTRING(Name, 1, 3) AS Name,
       Seller, 
       SUM(Qty) AS Qty 
FROM TABLE_NAME
GROUP BY Seller, SUBSTRING(Name, 1, 3)

我不確定ID是否始終為nn[-nn]格式,並且Name可以處理雞蛋以外的其他內容...

此方法在任何情況下均適用:

;with
m as (
    select *, nullif(charindex('-', ID), 0) div_id, nullif(charindex(' - ', name), 0) div_cat
    from EggTest 
),
c as (
    select *, 
        SUBSTRING(ID, 1, isnull(div_id-1, 1000)) main_ID, 
        SUBSTRING(name, 1, isnull(div_cat-1, 1000)) main_cat, 
        nullif(SUBSTRING(name, isnull(div_cat, 1000)+2, 1000), '') sub_cat
    from m
)
select main_ID ID, main_cat [Name], Seller, sum(qty) Qty
from c
group by main_ID, main_cat, seller

輸出:

ID  Name    Seller  Qty
10  Egg     Anna    13
10  Egg     Bob     11
10  Egg     John    10

暫無
暫無

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

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