我有一個有趣的問題,將表分成一組。我有一羣遊客 - 每個人說一種語言和/或是家庭的一部分。 我需要將表格分組,但我想將家庭和類似的語言說話者放在一起。分區表,但基於多列組合在一起
假設我想將遊客分成最多3人的團體(如果一個團體必須更大,那是可以接受的)。該解決方案不必非常聰明,以至於完全填補所有組織,但我正在盡力而爲。
輸入:
TouristID | LanguageID | FamilyID
---------------------------------
1 | 1 | 1
2 | 1 | 1
3 | 1 | 1
4 | 2 | 1
5 | 3 | 2
6 | 4 | 2
7 | 5 | 3
8 | 5 | 4
9 | 7 | 5
期望的結果:
TouristID | GroupID
-------------------
1 | 1
2 | 1
3 | 1
4 | 1
5 | 2
6 | 2
7 | 3
8 | 3
9 | 2
組1是由所有語言1個揚聲器,包括不能被排除在一個家族成員形成。
組2由兩個家庭成員形成(5,6)和一個隨機構件(9),以使該組的3
組3由兩個相同的語言揚聲器(7,8形成)
我所做的:
INSERT TouristGroup
SELECT
t.TouristID,
DENSE_RANK() OVER (ORDER BY GroupID) AS [GroupID]
FROM Tourists t
CROSS APPLY (
SELECT MIN(TouristID) AS [GroupID]
FROM Tourists t2
WHERE
(t2.LanguageID = t.LanguageID
OR t2.FamilyID = t.FamilyID)
) x;
INSERT Groups
SELECT GroupID, COUNT(*)
FROM TouristGroup
GROUP BY GroupID;
declare
@matchID int = 0,
@currentCount int,
@desiredCount int = 0,
@candidateGroupID int = null,
@chunk int = 1
while exists (
select null
from Groups g
left join Matches m
on m.GroupID = g.GroupID
where m.GroupID is null
)
begin
set @currentCount = null
set @candidateGroupID = null
select
@currentCount = isnull(SUM([Count]), 0)
from Matches m
join Groups g
on g.GroupID = m.GroupID
where m.MatchID = @matchID
if @CurrentCount is not null
begin
set @desiredCount = @chunk - @desiredCount
select top 1
@candidateGroupID = g.GroupID
from Groups g
left join Matches m
on m.GroupID = g.GroupID
where g.[Count] <= @desiredCount
and m.GroupID is null
order by [Count] DESC
if @candidateGroupID is not null
begin
insert Matches
select @matchID, @candidateGroupID
end
else begin
set @matchID = @matchID + 1
end
end
else begin
set @matchid = @matchID + 1
end
end
問題
是否有更好的方法來分區表,但基於多列將行分組在一起?
你說的是實際的[table partitioning](http://msdn.microsoft.com/en-us/library/ms190787.aspx)?或者爲結果集分組數據? – supergrady 2013-03-21 02:39:00
分組。在我上面創建的例子中,我需要將遊客分成幾組,但我想讓家人和類似語言的人聚在一起。對於那些不符合3人小組的人,他們被合併。即遊客9與5和6結合 – 2013-03-21 05:30:56
什麼版本的SQL Server? – 2013-03-21 19:50:54