SQL SERVER业务案例中的过度分区
我需要一些帮助来回答一个问题。我在SQLServer2012工作。基本上是这样的: 客户可以购买三种产品: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
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、年、月、产品、客户