Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL SERVER业务案例中的过度分区_Sql_Sql Server_Sql Server 2012_Window Functions - Fatal编程技术网

SQL SERVER业务案例中的过度分区

SQL SERVER业务案例中的过度分区,sql,sql-server,sql-server-2012,window-functions,Sql,Sql Server,Sql Server 2012,Window Functions,我需要一些帮助来回答一个问题。我在SQLServer2012工作。基本上是这样的: 客户可以购买三种产品: A B C 如果客户在同一天购买了两种产品(任何组合,例如,a+B或B+C或CA,导致两种已售出产品的任何组合),我们应将其显示为“双重” 如果客户在同一天只购买了一种产品,那么我们应该称之为“单一” 如果客户在同一天购买了所有三个产品,我们应该称之为“三个” 这就是我目前的数据: YearMonth Product CustomerNr Sales Date

我需要一些帮助来回答一个问题。我在SQLServer2012工作。基本上是这样的:

客户可以购买三种产品:

  • A
  • B
  • C
  • 如果客户同一天购买了两种产品(任何组合,例如,a+B或B+C或CA,导致两种已售出产品的任何组合),我们应将其显示为“双重

    如果客户在同一天只购买了一种产品,那么我们应该称之为“单一”

    如果客户在同一天购买了所有三个产品,我们应该称之为“三个

    这就是我目前的数据:

       YearMonth   Product CustomerNr        Sales Date
        201505      B      70056844         20150501
        201505      A      70056844         20150501
        201505      B      70057297         20150503
        201505      A      70057494         20150504
        201505          B      70057494         20150504
        201505      C      70057494         20150504
        201505      B      70033055         20150506
        201505      B      36021632         20150508
        201505      A      70060612         20150508
        201505      C      70060612         20150508
    
    正如我们在样本数据中看到的,客户编号70060612在同一销售日期购买了两种产品A和C,因此我们可以说他购买了双包装。客户编号:70057494在同一销售日期购买了3种产品,A、B和C。我们可以称之为三重

    我希望我的数据包含如下列:

       YearMonth   Product CustomerNr        Sales Date  Package        
        201505      B      70056844         20150501    Dual
        201505      A      70056844         20150501    Dual
        201505      B      70057297         20150503    Single
        201505      A      70057494         20150504    Triple
        201505          B      70057494         20150504    Triple
        201505      C      70057494         20150504    Triple
        201505      B      70033055         20150506    Single
        201505      B      36021632         20150508    Single
        201505      A      70060612         20150508    Dual
        201505      C      70060612         20150508    Dual
    
    我该怎么做?我想做一些类似的事情

     Test=COUNT(*) OVER (PARTITION BY CustomerNr)
    

    这是一个具有相应数据示例的解决方案。希望这对你有帮助

    create table #t(dt datetime, prod char(1), customer int)
    declare @date datetime = getdate()
    
    insert into #t(dt,prod,customer)
    values(@date,N'A',1),(@date,N'A',1),(@date,N'C',1),(@date,N'B',2),(@date,N'C',2),(@date,N'B',3),(@date,N'A',3),(@date,N'A',4),(@date,N'B',5),(@date,N'C',6),
    (@date,N'A',7),(@date,N'B',7),(@date,N'C',7)
    
    
    SELECT dt,prod,customer, MAX(cntDay) OVER(PARTITION BY customer, dt) as cntDay, 
        CASE MAX(cntDay) OVER(PARTITION BY customer, dt)
            WHEN 2 THEN N'Dual'
            WHEN 3 THEN N'Triple'
            ELSE N'Single' END as package -- Your Case
    FROM (
        SELECT *, DENSE_RANK() OVER(PARTITION BY customer, dt ORDER BY prod) as cntDay
        FROM #t
    ) as dat
    ORDER BY customer, dt -- just for a better overview
    
    drop table #t
    

    致以最良好的祝愿,爱奥尼亚

    不幸的是,SQL不允许对进行计数(不同的),
    densite\u RANK()
    是一种解决方法

    DECLARE @Table table
    (
        id int identity(1,1) primary key,
        YearMonth int,
        Product char(1),
        CustomerNr int,
        SalesDate date
    )
    
    INSERT @Table VALUES
    (201505, 'B', 70056844, '20150501'),
    (201505, 'A', 70056844, '20150501'),
    (201505, 'B', 70057297, '20150503'),
    (201505, 'A', 70057494, '20150504'),
    (201505, 'B', 70057494, '20150504'),
    (201505, 'C', 70057494, '20150504'),
    (201505, 'B', 70033055, '20150506'),
    (201505, 'B', 36021632, '20150508'),
    (201505, 'A', 70060612, '20150508'),
    (201505, 'C', 70060612, '20150508'),
    (201505, 'A', 70056844, '20150501') -- Additional for duplicated product
    
    SELECT 
        *, 
        CASE 
            DENSE_RANK() OVER (PARTITION BY CustomerNr, SalesDate ORDER BY Product)
             + DENSE_RANK() OVER (PARTITION BY CustomerNr, SalesDate ORDER BY Product DESC) - 1
            WHEN 1 THEN 'Single'
            WHEN 2 THEN 'Dual'
            WHEN 3 THEN 'Triple'
            ELSE 'Multiple' -- Not defined case 
        END AS Package
    FROM 
        @Table
    ORDER BY 
        id
    
    结果

    id          YearMonth   Product CustomerNr  SalesDate  Package
    ----------- ----------- ------- ----------- ---------- --------
    1           201505      B       70056844    2015-05-01 Dual
    2           201505      A       70056844    2015-05-01 Dual
    3           201505      B       70057297    2015-05-03 Single
    4           201505      A       70057494    2015-05-04 Triple
    5           201505      B       70057494    2015-05-04 Triple
    6           201505      C       70057494    2015-05-04 Triple
    7           201505      B       70033055    2015-05-06 Single
    8           201505      B       36021632    2015-05-08 Single
    9           201505      A       70060612    2015-05-08 Dual
    10          201505      C       70060612    2015-05-08 Dual
    11          201505      A       70056844    2015-05-01 Dual
    

    这里有一个“教科书上的例子”,使用你提到的方法。看看例子B。你没有考虑到实现单次、双次或三次销售所需的不同组合。您的解决方案将同一客户在同一天的两次销售视为双重销售。更正了演示。谢谢你的提示。现在它算对了。我有个问题。很高兴你带来了重复的一行,ID 11。如果客户在同一天购买了ID 2和ID 11,并且购买了相同的产品,但每个产品(A)都有不同的服务ID,那么如何进行限制,以便我在特定的一天仅提取客户编号的每个产品的一行?示例不应提取产品A的两行。每天每个产品只能有一行。@user3197575是的,您可以在计算
    包之前筛选表<代码>从@表组中按年、月、产品、客户选择最小(id)id、最小(SalesDate)SalesDate、年、月、产品、客户