2014-08-30 55 views
-1

我们有如下所示分配组号条件

enter image description here

一个表,我们要写入与生成组ID查询(基于以下)

如果一个国家然后[国家,类别]组记录应该被分配一个唯一的组ID,

所以对于上面的表,我们需要编写单个查询(没有存储过程或功能)这将返回如下结果。

enter image description here

我们试图查询其模样非常复杂,无法读取。

所以我们正在寻找更好的查询来实现相同。

预先感谢您

+2

使用SQL Server?用两个不同的dbs标记。 – 2014-08-30 00:17:54

+0

有点看起来像访问... – vol7ron 2014-08-30 00:55:27

回答

2

假设SQL Server中,您可以通过DENSE_RANK()加入OVER()COUNT()和使用CASE语句做到这一点:

;with cte AS (SELECT *,COUNT(*) OVER(PARTITION BY Country,Category) CT 
         ,CASE WHEN Category IS NOT NULL THEN DENSE_RANK() OVER (ORDER BY Country) END Rank_ 
       FROM Table1) 
SELECT Country 
     ,State 
     ,Category 
     ,CASE WHEN CT > 1 AND Rank_ IS NOT NULL THEN DENSE_Rank() OVER(ORDER BY Rank_ DESC) END AS Group_ 
FROM cte 
ORDER BY Country DESC,State 

演示:SQL Fiddle

只有当你关心它从1-n开始编号是否需要多个DENSE_RANK()

+0

完美的解决方案正在寻找,仍然是我的情况下的大型SQL。但是这个更易读易维护。非常感谢你 – 2014-09-02 01:23:53

0

您可以在SQL Server这样做,因为:

select t.*, cs.groupnum 
from table t left outer join 
    (select country, category, count(*) as cnt, 
      dense_rank() over (order by country, category) as groupnum 
     from table t 
     group by country, category 
     having count(*) > 1 
    ) cs 
    on t.country = cs.country and t.category = cs.category; 

在MySQL中,你可以做这个使用变量而不是dense_rank()的变体。

1

如果你使用MySQL,你可以使用以下命令:

小提琴:http://sqlfiddle.com/#!2/0f381/7/0

select t.country, t.state, t.category, v.grp 
    from (select x.*, @r := @r + 1 as grp 
      from (select country, category 
        from tbl 
       where category is not null 
       group by country, category 
       having count(*) > 1 
       order by category, state, country) x 
     cross join (select @r := 0) r) v 
right join tbl t 
    on v.country = t.country 
    and v.category = t.category 
+0

这也是可行的。谢谢。 – 2014-09-02 16:48:47

0
DROP TABLE #TEST 

GO 

CREATE TABLE #Test(
    Country NVARCHAR(100) 
    ,[State] NVARCHAR(100) 
    ,Category NVARCHAR(100) 
    ,GroupID INT); 

GO 

INSERT INTO #Test 
    (Country, State, Category) 
VALUES 
    ('US','AZ','G1'), 
    ('US','AL','G1'), 
    ('US','NY',null), 
    ('UK','TN','G1'), 
    ('UK','MH','G1'), 
    ('UK','AP','G3'), 
    ('CA','MI',null), 
    ('CA','CA',null); 


UPDATE 
    T2 
SET 
    T2.GroupID = T.RANKED_ID 
FROM 
    (SELECT COUNT(*) 'Count' 
      ,Country 
      ,Category 
      ,DENSE_RANK() OVER (ORDER BY Country DESC) AS Ranked_ID 
     FROM #Test 
     WHERE Category IS NOT NULL 
     GROUP BY Country, Category 
     HAVING COUNT(*) > 1 
    ) AS T 
    JOIN #Test T2 
    ON T.Category = T2.Category 
    AND T.Country = T2.Country 


SELECT * 
FROM #TEST