总结SQL中的一列

时间:2018-08-25 05:48:20

标签: sql-server tsql

我的数据库中有四个表,即Star Schema Design。这些表是

  1. Product_DM(产品ID,产品名称)
  2. Shop_DM(分支ID,分支名称,分支州)
  3. Date_DM(日期ID为日期,日期,月份,月份和年份)。根据Date_Id填充日,月和年值。
  4. 收入FT(产品ID,分支ID,日期ID,数量)

我想拥有的是我想看看在节礼日的最后五年出售大多数产品的5家分店。

SELECT 
    RF.BRANCH_ID,
    SD.BRANCH_NAME,
    SD.BRANCH_STATE,
    PD.PRODUCT_NAME,
    SELF_RF.TOTAL,
    FORMAT ( DD.[date], 'd', 'en-US' ) AS 'Great Britain English Result'
FROM 
    PRODUCT_DM  AS PD,
    SHOP_DM     AS SD,
    DATE_DM     AS DD,
    REVENUE_FT  AS RF
JOIN 
    (SELECT BRANCH_ID, [date], SUM(quantity) AS TOTAL
     FROM REVENUE_FT
     GROUP BY BRANCH_ID, [date]) AS SELF_RF ON SELF_RF.BRANCH_ID = RF.BRANCH_ID 
                                            AND SELF_RF.[date] = RF.[date]
WHERE   
    RF.BRANCH_ID = SD.BRANCH_ID  
    AND SD.BRANCH_STATE = 'NSW'         
    AND RF.[date] = DD.[date]     
    AND DD.[day] = 26            
    AND DD.[month] = 12            
    AND DD.[year] BETWEEN 2012 AND 2018
ORDER BY 
    SELF_RF.TOTAL DESC;

这是我的查询,这是结果:

enter image description here

问题在于它不是要汇总不同的产品和不同的日期(例如12/26/201312/26/2014也应该汇总)。我知道我在查询中做错了事,但我需要帮助。

1 个答案:

答案 0 :(得分:1)

请参见下面的示例,在该示例中,您可以获得过去5个节礼日销售量最高的前5家分支机构/商店。

这是一个基于您上面列出的表结构的示例。

;with GetBranchDetailsAndData
as
(
    --Joins the date table, sales, and shop details to get the branch details and quantity per transaction
    SELECT 
        c.Branch_Id,
        c.Branch_Name,
        c.Branch_State,
        a.Quantity
    FROM 
        Revenue_FT a
    INNER JOIN 
        DATE_DM  b
    ON 
        a.Date_Id = b.Date_Id
    INNER JOIN 
        Shop_DM c
    ON 
        c.Branch_Id = a.Branch_Id
    WHERE 
        [DAY] = 26 AND 
        [Month] = 12
        AND [Year] BETWEEN 2012 AND 2017 --Boxing days in 2012 - 2017
        --You could also filter on a specific state in the where clause

),
SUMDetailsAndData
as
(
    SELECT
        Branch_ID,
        Branch_Name,
        Branch_State, 
        SUM(Quantity) as [Quantity] --Sum quantity per branch
    FROM 
        GetBranchDetailsAndData
    GROUP BY
        Branch_ID,
        Branch_Name,
        Branch_State
), 
GetTop5
as
(
    SELECT
        Branch_ID,
        Branch_Name,
        Branch_State,
        Quantity,
        DENSE_RANK() OVER(ORDER BY Quantity DESC) as [QuantityOrder] --DENSE RANK to get the quantity order 
    FROM 
        SUMDetailsAndData
)
SELECT
    *
FROM
    GetTop5
WHERE 
    QuantityOrder <= 5 --Where the quantity order less or equal to 5. This will return multiple rows if there is multiple with the same number in the top 5. 
ORDER BY 
    QuantityOrder

这是我用来生成测试数据的摘要。

--Create tables
CREATE TABLE Product_DM (Product_Id bigint identity(1,1), Product_Name NVARCHAR(200))
CREATE TABLE Shop_DM (Branch_Id bigint identity(1,1), Branch_Name NVARCHAR(100), Branch_State NVARCHAR(100))
CREATE TABLE Date_DM (Date_Id bigint identity(1,1), [Day] int, [Month] int, [Year] int)
CREATE TABLE Revenue_FT (Product_id bigint, Branch_Id bigint, Date_Id bigint, Quantity bigint)
--Insert Data
INSERT INTO Product_DM (Product_Name) VALUES ('Test Product'),('Test Product2')
INSERT INTO Shop_DM (Branch_Name, Branch_State) VALUES 
('Branch1', 'State1'), ('Branch2', 'State1'), ('Branch3', 'State1'), ('Branch4', 'State1'), ('Branch5', 'State1'), 
('Branch6', 'State1'), ('Branch7', 'State1'), ('Branch8', 'State1'), ('Branch9', 'State1'), ('Branch10', 'State1')

DECLARE @DateStart date = '2010-01-01', @DateEnd date = '2018-01-01'
WHILE(@DateStart <= @DateEnd) 
BEGIN
    INSERT INTO DATE_DM ([day], [month], [year]) VALUES (DATEPART(dd, @datestart), DATEPART(MM, @datestart), DATEPART(YYYY, @datestart))
    SET @DateStart = DATEADD(dd, 1, @DateStart)
END

--Insert random product sales
DECLARE @MinProduct int = 1, @MaxProduct int = 2
DECLARE @MinBranch int = 1, @MaxBranch int = 10
DECLARE @MinDate int = 1, @MaxDate int = 2923
DECLARE @Startloop int = 1, @EndLoop int = 200000

WHILE @Startloop <= @EndLoop
BEGIN
    INSERT INTO Revenue_FT VALUES (
            ROUND(((@MaxProduct - @MinProduct) * RAND() + @MinProduct), 0), 
            ROUND(((@MaxBranch - @MinBranch) * RAND() + @MinBranch), 0), 
            ROUND(((@MaxDate - @MinDate) * RAND() + @MinDate), 0), 1)

    SET @Startloop = @Startloop + 1
END

以下示例输出:

Output