SQL Server 2012 - 一点指导

时间:2016-10-03 14:32:59

标签: sql sql-server sql-server-2012

我搜索了网络,但我确信我不能正确地删除我的关键字,因为我找不到解决问题的方法。认为这可能是递归,但我不太确定。

我有一个包含以下类别的表:

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

很可能同一个客户可以找到数百次多本书,因此最终的组类别将代表该客户的唯一价值(其他客户只有在他们检查的所有内容也匹配所有内容时才具有相同的价值其他客户已经退房了。)

使用上述数据,哈利和简有完全相同的作者签出,所以他们在同一组,但约翰和史蒂文有不同的组合,所以他们有自己独特的组。

希望这是有道理的。这是什么叫做递归?如果是这样,那么我将寻找一个cte解决方案,它使用某种排名来获得唯一的id值。谢谢你给予的任何帮助。

3 个答案:

答案 0 :(得分:0)

不确定如何获得确切的群组订单,但只是将客户组合在一起,您可以将他们的作者与FOR XML结合起来,并根据完全匹配对客户进行分组。

//calls myFunction after 1 second and passes 2 parameters:
TweenMax.delayedCall(1, myFunction, ["param1", "param2"]);

function myFunction(param1, param2) {
    //do stuff
}

SQL FIDDLE DEMO

答案 1 :(得分:0)

尝试使用游标......游标很慢,但它们也更容易理解..

这是一个示例实现......

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

答案 2 :(得分:0)

您应该能够使用标准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