2016-05-31 84 views
2

我想将子类别映射到“多数”父类别。寻找这个例子:多数票TSQL

IF OBJECT_ID(N'tempdb..#Temp') IS NOT NULL DROP TABLE #Temp 

CREATE TABLE #Temp 
(
    ID INT, 
    SubCategory NVARCHAR(100), 
    Category NVARCHAR(100) 
) 

INSERT INTO #Temp 
    SELECT 1, N'SC1', N'C1' 
     UNION 
    SELECT 2, N'SC1', N'C1' 
     UNION 
    SELECT 3, N'SC1', N'C1' 
     UNION 
    SELECT 4, N'SC1', N'C2' 
     UNION 
    SELECT 5, N'SC1', N'C2' 

子类别SC1可以属于2“父”的类别:C1,C2,但C1所以它代表了大多数被分配更多的SC1大于C2。我目前使用相关子查询来映射阳光类别的多数家长产品分类如下:

IF OBJECT_ID(N'tempdb..#Temp') IS NOT NULL DROP TABLE #Temp 

CREATE TABLE #Temp 
(
    ID INT, 
    SubCategory NVARCHAR(100), 
    Category NVARCHAR(100) 
) 

INSERT INTO #Temp 
    SELECT 1, N'SC1', N'C1' 
     UNION 
    SELECT 2, N'SC1', N'C1' 
     UNION 
    SELECT 3, N'SC1', N'C1' 
     UNION 
    SELECT 4, N'SC1', N'C2' 
     UNION 
    SELECT 5, N'SC1', N'C2' 

SELECT 
    Id, 
    OuterQuery.SubCategory, 
    Category = (SELECT TOP 1 Category FROM #Temp AS InnerQuery 
       WHERE InnerQuery.SubCategory = OuterQuery.SubCategory 
       GROUP BY InnerQuery.SubCategory, InnerQuery.Category      
       ORDER BY COUNT(DISTINCT Id) DESC) 
FROM #Temp AS OuterQuery 

这是想实现我想要的正确方法是什么?

+1

如果两个(或多个)类别对于一个子类别具有同样高的计数,会发生什么?查询应该返回两个(或更多)行吗?或者有某种形式的平局规则?或者是其他东西? –

+0

知道有人会问( - :.在这种情况下,我不太可能出现这种情况,我只是选择第一个(TOP 1)。 – cs0815

+0

为什么一个子类别可以多次在同一个类别中?其他的? –

回答

2

我会做这样的:

DECLARE @t TABLE (
    ID INT, 
    SubCategory NVARCHAR(100), 
    Category NVARCHAR(100) 
) 

INSERT INTO @t 
    VALUES 
    (1, N'SC1', N'C1'), 
    (2, N'SC1', N'C1'), 
    (3, N'SC1', N'C1'), 
    (4, N'SC1', N'C2'), 
    (5, N'SC1', N'C2'), 
    (6, N'SC2', N'C2'), 
    (7, N'SC2', N'C2'), 
    (8, N'SC2', N'C3'); 

WITH a AS (
    SELECT 
     subcategory, 
     category, 
     COUNT(id) cnt 
    FROM @t 
    GROUP BY 
     SubCategory, 
     category 
), b as (
    SELECT 
     subcategory, 
     category, 
     ROW_NUMBER() OVER 
      (PARTITION BY subcategory ORDER BY cnt DESC) row 
    FROM a 
) 
SELECT 
    subcategory, 
    category AS Majority 
FROM b 
WHERE row = 1 

这产生的结果:

subcategory Majority 
SC1 C1 
SC2 C2 
+0

是的,这是我会的你也认为PARTITION BY的表现会更好,并且/或者我的方法根本上是错误的吗? – cs0815

+1

这取决于你猜表格的大小,如果只有5条记录,我猜它们会大致相同,但如果你有成千上万的行你会做一个在内部查询中为外部查询中的每一行选择top 1。比较你运行时的实际执行计划他们都会看到他们如何处理您的数据。 – PeterO

+0

你是否错过了where行= 1? – Paparazzi

1

有这样只有子查询;

测试数据(我已经增加了范围本)

IF OBJECT_ID(N'tempdb..#Temp') IS NOT NULL DROP TABLE #Temp 

CREATE TABLE #Temp 
(ID INT, SubCategory NVARCHAR(100), Category NVARCHAR(100)) 

INSERT INTO #Temp (ID, SubCategory, Category) 
VALUES 
(1, N'SC1', N'C1') 
,(2, N'SC1', N'C1') 
,(3, N'SC1', N'C1') 
,(4, N'SC1', N'C2') 
,(5, N'SC1', N'C2') 
,(6, N'SC2', N'C3') 
,(7, N'SC2', N'C3') 
,(8, N'SC2', N'C2') 
,(9, N'SC2', N'C2') 
,(10, N'SC2', N'C2') 
,(11, N'SC2', N'C2') 

现在查询;

SELECT DISTINCT 
t.SubCategory 
,t.Category 
FROM #Temp t 

JOIN 
(
    SELECT 
    SubCategory 
    ,Category 
    ,COUNT(SubCategory) Ct 
    FROM #Temp 
    GROUP BY SubCategory, Category 
    ) Cont 
ON t.SubCategory = cont.SubCategory 
AND t.Category = cont.Category 

JOIN 
(
    SELECT 
    a.SubCategory 
    ,MAX(a.Ct) MaxCount 
    FROM 
    (
     SELECT 
     SubCategory 
     ,Category 
     ,COUNT(SubCategory) Ct 
     FROM #Temp 
     GROUP BY SubCategory, Category 
    ) a 
    GROUP BY a.SubCategory 
) maxi ON t.SubCategory = maxi.SubCategory 
AND cont.Ct = maxi.MaxCount