它看起來像主的混亂是由你的SQL語句的問題,你只需GROUP BY LASTNAME, HOUSENO
的開始引起落實。
如果你想要一個簡單的分組,你的查詢將是正確的。但是,那麼您向我們展示了一個具有預期結果的更詳細的示例數據,並且很明顯,您不僅需要一個分組(它不關心數據中行的順序),而且希望根據它們對行進行分組序列。
這是一個經典問題gaps-and-islands
。在SQL Server 2008中,可以使用對ROW_NUMBER
函數的少量調用來完成。
的樣本數據
DECLARE @T TABLE
(id int PRIMARY KEY
,FirstName nvarchar(50)
,LastName nvarchar(50)
,HouseNo nvarchar(50)
,MyCount int
,CountId int);
INSERT INTO @T (id, FirstName, LastName, HouseNo) VALUES
(1 , 'Imran ', 'Khan ', '1-1'),
(2 , 'Waseem', 'Khan ', '1-1'),
(3 , 'Rihan ', 'Khan ', '1-1'),
(4 , 'Moiz ', 'Shaikh', '1-2'),
(5 , 'Zbair ', 'Shaikh', '1-2'),
(6 , 'Sultan', 'Shaikh', '1-2'),
(7 , 'Zaid ', 'Khan ', NULL),
(10, 'Parvez', 'Patel ', '1-3'),
(11, 'Ahmed ', 'Patel ', '1-3'),
(12, 'Rahat ', 'Syed ', '1-4'),
(13, 'Talha ', 'Khan ', NULL),
(14, 'Zia ', 'Khan ', NULL),
(15, 'Arshad', 'Patel ', '1-3'),
(16, 'Samad ', 'Patel ', '1-3'),
(17, 'Raees ', 'Syed ', '1-4'),
(18, 'Azmat ', 'Khan ', NULL),
(19, 'Imran ', 'Khan ', NULL);
SELECT查詢
WITH
CTE_RN
AS
(
SELECT
id
,FirstName
,LastName
,HouseNo
,MyCount
,CountId
,ROW_NUMBER() OVER (PARTITION BY LastName, HouseNo ORDER BY ID) AS rn1
,ROW_NUMBER() OVER (ORDER BY ID) AS rn2
FROM @T AS T
)
,CTE_GRoups
AS
(
SELECT
id
,FirstName
,LastName
,HouseNo
,MyCount
,CountId
,rn1
,rn2
,rn2-rn1 AS GroupNumber
,COUNT(ID) OVER (PARTITION BY LastName, HouseNo, rn2-rn1) AS NewMyCount
,MIN(ID) OVER (PARTITION BY LastName, HouseNo, rn2-rn1) AS GroupMinID
FROM CTE_RN
)
SELECT
id
,FirstName
,LastName
,HouseNo
,rn1
,rn2
,GroupNumber
,NewMyCount
,GroupMinID
,DENSE_RANK() OVER (ORDER BY GroupMinID) AS NewCountId
FROM CTE_GRoups
ORDER BY ID;
結果
+----+-----------+----------+---------+-----+-----+-------------+------------+------------+------------+
| id | FirstName | LastName | HouseNo | rn1 | rn2 | GroupNumber | NewMyCount | GroupMinID | NewCountId |
+----+-----------+----------+---------+-----+-----+-------------+------------+------------+------------+
| 1 | Imran | Khan | 1-1 | 1 | 1 | 0 | 3 | 1 | 1 |
| 2 | Waseem | Khan | 1-1 | 2 | 2 | 0 | 3 | 1 | 1 |
| 3 | Rihan | Khan | 1-1 | 3 | 3 | 0 | 3 | 1 | 1 |
| 4 | Moiz | Shaikh | 1-2 | 1 | 4 | 3 | 3 | 4 | 2 |
| 5 | Zbair | Shaikh | 1-2 | 2 | 5 | 3 | 3 | 4 | 2 |
| 6 | Sultan | Shaikh | 1-2 | 3 | 6 | 3 | 3 | 4 | 2 |
| 7 | Zaid | Khan | NULL | 1 | 7 | 6 | 1 | 7 | 3 |
| 10 | Parvez | Patel | 1-3 | 1 | 8 | 7 | 2 | 10 | 4 |
| 11 | Ahmed | Patel | 1-3 | 2 | 9 | 7 | 2 | 10 | 4 |
| 12 | Rahat | Syed | 1-4 | 1 | 10 | 9 | 1 | 12 | 5 |
| 13 | Talha | Khan | NULL | 2 | 11 | 9 | 2 | 13 | 6 |
| 14 | Zia | Khan | NULL | 3 | 12 | 9 | 2 | 13 | 6 |
| 15 | Arshad | Patel | 1-3 | 3 | 13 | 10 | 2 | 15 | 7 |
| 16 | Samad | Patel | 1-3 | 4 | 14 | 10 | 2 | 15 | 7 |
| 17 | Raees | Syed | 1-4 | 2 | 15 | 13 | 1 | 17 | 8 |
| 18 | Azmat | Khan | NULL | 4 | 16 | 12 | 2 | 18 | 9 |
| 19 | Imran | Khan | NULL | 5 | 17 | 12 | 2 | 18 | 9 |
+----+-----------+----------+---------+-----+-----+-------------+------------+------------+------------+
在這裏,我包括在結果所有中間步驟,所以你可以看到它是如何工作的。主要部分是兩套ROW_NUMBER
s。 rn1
序列重新啓動爲每個LastName, HouseNo
。它由LastName, HouseNo
分區。 rn2
是一個簡單的增加序列沒有差距。我們需要它,因爲原始ID
定義了順序,但可能有空白。
然後我們減去這兩個序列,差異給我們GroupNumber
。
計算組中元素的數量很簡單COUNT
,這給了我們NewMyCount
。
用兩個步驟完成無間隙序列號的枚舉。起初MIN
給出了一個組的標識符,然後DENSE_RANK
生成一個沒有間隙的序列NewCountId
。
如果你想真正與計算NewMyCount
和NewCountId
更新原來的表,很容易打開SELECT
上面的查詢到UPDATE
查詢:
UPDATE查詢
WITH
CTE_RN
AS
(
SELECT
id
,FirstName
,LastName
,HouseNo
,MyCount
,CountId
,ROW_NUMBER() OVER (PARTITION BY LastName, HouseNo ORDER BY ID) AS rn1
,ROW_NUMBER() OVER (ORDER BY ID) AS rn2
FROM @T AS T
)
,CTE_GRoups
AS
(
SELECT
id
,FirstName
,LastName
,HouseNo
,MyCount
,CountId
,rn1
,rn2
,rn2-rn1 AS GroupNumber
,COUNT(ID) OVER (PARTITION BY LastName, HouseNo, rn2-rn1) AS NewMyCount
,MIN(ID) OVER (PARTITION BY LastName, HouseNo, rn2-rn1) AS GroupMinID
FROM CTE_RN
)
,CTE_Update
AS
(
SELECT
id
,FirstName
,LastName
,HouseNo
,MyCount
,CountId
,rn1
,rn2
,GroupNumber
,NewMyCount
,GroupMinID
,DENSE_RANK() OVER (ORDER BY GroupMinID) AS NewCountId
FROM CTE_GRoups
)
UPDATE CTE_Update
SET
MyCount = NewMyCount
,CountId = NewCountId
;
結果
SELECT *
FROM @T
ORDER BY ID;
+----+-----------+----------+---------+---------+---------+
| id | FirstName | LastName | HouseNo | MyCount | CountId |
+----+-----------+----------+---------+---------+---------+
| 1 | Imran | Khan | 1-1 | 3 | 1 |
| 2 | Waseem | Khan | 1-1 | 3 | 1 |
| 3 | Rihan | Khan | 1-1 | 3 | 1 |
| 4 | Moiz | Shaikh | 1-2 | 3 | 2 |
| 5 | Zbair | Shaikh | 1-2 | 3 | 2 |
| 6 | Sultan | Shaikh | 1-2 | 3 | 2 |
| 7 | Zaid | Khan | NULL | 1 | 3 |
| 10 | Parvez | Patel | 1-3 | 2 | 4 |
| 11 | Ahmed | Patel | 1-3 | 2 | 4 |
| 12 | Rahat | Syed | 1-4 | 1 | 5 |
| 13 | Talha | Khan | NULL | 2 | 6 |
| 14 | Zia | Khan | NULL | 2 | 6 |
| 15 | Arshad | Patel | 1-3 | 2 | 7 |
| 16 | Samad | Patel | 1-3 | 2 | 7 |
| 17 | Raees | Syed | 1-4 | 1 | 8 |
| 18 | Azmat | Khan | NULL | 2 | 9 |
| 19 | Imran | Khan | NULL | 2 | 9 |
+----+-----------+----------+---------+---------+---------+
您由LASTNAME,HOUSENO分組。 A/NULL和K/NULL顯然是兩個不同的組,所以我沒有看到你的查詢如何給你一個5的合併計數。請問'SELECT LASTNAME,HOUSENO,COUNT(ID)'而不是'SELECT COUNT(ID)',以查看哪個組獲得5的計數? –
我剛剛檢查過它。您的查詢 - 除了錯字GRUOP/GROUP之外,*不會*返回5,而是分別返回3和2,就像您想要的一樣,並且我確信它會。這裏是SQL小提琴:http://sqlfiddle.com/#!6/c536b/2。所以你可以在我看來完全刪除這個問題。 –