2014-08-30 39 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