我们有一个如下表格
我们想要编写一个带有生成的组ID的查询(基于以下内容)
如果某个国家/地区的商品具有相同类别的商品数超过1个,则应为[国家/地区,类别]组记录分配唯一的组ID
因此,对于上表,我们需要编写单个查询(没有存储过程或函数),这将返回如下所示的结果。
我们尝试了查询,看起来非常复杂且无法读取。
所以我们正在寻找更好的查询来实现同样的目标。
提前谢谢
答案 0 :(得分:2)
假设SQL Server,您可以通过将OVER()
添加到COUNT()
并将CASE
语句与DENSE_RANK()
一起使用来实现此目的:
;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()
。
答案 1 :(得分: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
答案 2 :(得分: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()
来对此进行变体。
答案 3 :(得分: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