[英]SQL Server 2012 - A Little Guidance
我已經在網上搜索過,但是我確信我不能正確地輸入關鍵詞,因為我沒有找到可能的解決方案。 認為這可能是遞歸,但我不確定。
我有一個具有以下類別的表:
ID, Author, Customer, Group
樣本數據集將類似於:
ID | Author | Customer | Group
------------------------------------------
1 | Paula Hawkins | John Doe | NULL
2 | Harlan Coben | John Doe | NULL
3 | James Patterson| John Doe | NULL
4 | Paula Hawkins | Jane Doe | NULL
5 | James Patterson| Jane Doe | NULL
6 | James Patterson| Steven Doe| NULL
7 | Harlan Coben | Steven Doe| NULL
8 | Paula Hawkins | Harry Doe | NULL
9 | James Patterson| Harry Doe | NULL
客戶可能有一個或多個礦石,然后有一位作者簽出,因此我要嘗試的是根據簽出的總數(與客戶姓名無關)將他們與唯一的ID分組:
ID | Author | Customer | Group
--------------------------------------------
1 | Paula Hawkins | John Doe | 1
2 | Harlan Coben | John Doe | 1
3 | James Patterson| John Doe | 1
4 | Paula Hawkins | Jane Doe | 2
5 | James Patterson| Jane Doe | 2
6 | James Patterson| Steven Doe | 3
7 | Harlan Coben | Steven Doe | 3
8 | Paula Hawkins | Harry Doe | 2
9 | James Patterson| Harry Doe | 2
很有可能數百次找到同一位客戶的多本書,因此最終的組類別將代表該客戶的獨特價值(其他客戶只有在他們簽出的所有內容也與另一位客戶擁有的所有內容匹配時,才具有相同的價值。檢查過了)。
使用以上數據,Harry和Jane的簽出作者完全相同,因此他們屬於同一組,而John和Steven的組合不同,因此他們有自己的獨特組。
希望這是有道理的。 這就是所謂的遞歸嗎? 如果是這樣,那么我將尋求一種使用某種排名作為唯一ID值的CTE解決方案。 感謝您的幫助。
不確定如何獲取准確的分組訂單,但是僅要將客戶分組在一起,可以將其作者與FOR XML結合在一起,並根據完全匹配的內容對客戶進行分組。
WITH cte AS (
SELECT
*,
RANK() OVER (ORDER BY Authors) [Group]
FROM (
SELECT
[Customer],
STUFF((SELECT ',' + [Author]
FROM myTable WHERE Customer = mt.Customer
ORDER BY Author
FOR XML PATH('')), 1, 1, '') AS Authors
FROM
myTable mt
GROUP BY [Customer] ) t
)
SELECT
mt.[ID],
mt.[Author],
mt.[Customer],
cte.[Group]
FROM
cte
JOIN myTable mt ON mt.Customer = cte.Customer
ORDER BY mt.[ID]
嘗試使用游標...游標很慢,但也更易於理解。
這是一個示例實現...
DECLARE @GroupExists Bit
DECLARE @CurrGroup Int
DECLARE @NextGroup Int
DECLARE @Customer VARCHAR(250)
SET @NextGroup = 1
DECLARE customer_cursor CURSOR FAST_FORWARD
FOR SELECT distinct Customer FROM dbo.TableName
OPEN customer_cursor
FETCH NEXT FROM customer_cursor
INTO @Customer
WHILE @@FETCH_STATUS = 0
BEGIN
SET @GroupExists = 0
--Test condition to check if group of authors in in use
IF @GroupExists = 1 Then
BEGIN
UPDATE dbo.TableName
SET Group = @CurrGroup
WHERE Customer = @Customer
END
ELSE
BEGIN
UPDATE dbo.TableName
SET Group = @NextGroup
WHERE Customer = @Customer
SET @NextGroup= @NextGroup+ 1
END
FETCH NEXT FROM customer_cursor
INTO @Customer
END
您應該能夠使用標准SQL生成組。 以下查詢可以完成這項工作; 但是,我不保證其性能。
WITH
CTE_CheckOutBookCount AS
(
SELECT [ID]
,[Author]
,[Customer]
,COUNT([Author]) OVER (PARTITION BY [Customer]) AS [CheckOutBooks] -- Count the number of books checked out by each customer. This will be used for our initial compare between customers.
FROM CheckedOutBooks
),
CTE_AuthorAndCountCompare AS
(
SELECT CB.[ID]
,CBC.[Customer] AS MatchedCustomers
FROM CTE_CheckOutBookCount CB
INNER JOIN CTE_CheckOutBookCount CBC ON CB.[Author] = CBC.[Author] AND CB.[CheckOutBooks] = CBC.[CheckOutBooks] --Join customer information on number of books checked out and author name of books checked out.
)
,CTE_MatchedCustomers
AS
(
SELECT
[ID]
,[Author]
,[Customer]
--Get the minimum record id of customers which match exactly on count and authors checked out. This will be used to help generate group ID.
,(
SELECT MIN(ID)
FROM CTE_AuthorAndCountCompare
WHERE CheckedOutBooks.[Customer] = CTE_AuthorAndCountCompare.MatchedCustomers
) MinID
FROM CheckedOutBooks
)
SELECT
[ID]
,[Author]
,[Customer]
,DENSE_RANK() OVER (ORDER BY MinID) AS [Group] -- Generate new group id
FROM CTE_MatchedCustomers
ORDER BY ID
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.