0

我在 SQL Server 2000 数据库中有以下表:

掌握

MasterID | Details   | [other fields]
=====================================
PK (int) | Free text | ...

日志表

LogID    | MasterID | UserID    | LogDate    | LogText
==========================================================
PK (int) | FK (int) | VarChar(2)| Date stamp | Free text

每个主记录可能有许多日志条目。

我有一个查询,它为每个主行提取最近的三个关联日志条目,如下所示。请注意,执行适当的转换和格式化以实现LogData连接(为清楚起见省略):

SELECT 
    M.MasterID, M.Details, L.LogDate + L.UserID + L.LogText AS LogData 
FROM
    MasterTable M 
INNER JOIN 
    LogTable L ON M.MasterID = L.MasterID 
    AND L.LogID IN (SELECT TOP 3 LogID FROM LogTable 
                    WHERE MasterID = M. MasterID ORDER BY LogDate DESC)

这会产生如下输出:

MasterID | Details | LogData
========================================================
1        | First   | 05/11/2012 AB Called Client  
2        | Second  | 08/11/2012 CD Client Visit  
2        | Second  | 07/11/2012 CD Called Client  
2        | Second  | 05/11/2012 AB Called Client  

我需要实现的是将第二个表中的数据显示为输出中的列,所有数据都针对每条主记录进行报告,从而避免重复数据。像这样:

MasterID | Details | LogData1                    | LogData2                    | LogData3
===========================================================================================================
1        | First   | 05/11/2012 AB Called Client | (null)                      | (null)  
2        | Second  | 08/11/2012 CD Client Visit  | 07/11/2012 CD Called Client | 05/11/2012 AB Called Client  

请注意,在现实世界的需求中,此解决方案将是扁平化 5 个表的一部分,输出由大约 20,000 行和 90 列数据组成。

提前致谢。

4

1 回答 1

1

我要发布这个,只是为了表明它可以完成,但强烈建议,不要通过 SQL 来完成。应该通过显示在您的列上更加动态的 UI 来完成。即使那样,我也会以不同的方式设计它。

-- create master table
DECLARE @MasterTable TABLE (
    [MasterID] [int] IDENTITY (1, 1) NOT NULL ,
    [Details] [varchar] (50) ,
    [AdditionalField_1] [varchar] (50) ,
    [AdditionalField_n] [varchar] (50) 
)
-- create log table
DECLARE @LogTable TABLE (
    [LogID] [int] IDENTITY (1, 1) NOT NULL ,
    [MasterID] [int] NULL ,
    [UserID] [varchar] (2) ,
    [LogDate] [datetime] NULL ,
    [LogText] [varchar] (50) 
) 
-- insert into master table
INSERT INTO @MasterTable  (Details)
        VALUES ('First')
INSERT INTO @MasterTable  (Details)
        VALUES ('Second') 
-- insert into log table
INSERT INTO @LogTable  (MasterID, UserID, LogDate, LogText)
        VALUES (1, 'AB', '05/11/2012', 'Called Client')   
INSERT INTO @LogTable  (MasterID, UserID, LogDate, LogText)
        VALUES (2, 'AB', '05/11/2012', 'Called Client')   
INSERT INTO @LogTable  (MasterID, UserID, LogDate, LogText)
        VALUES (2, 'CD', '07/11/2012', 'Called Client')   
INSERT INTO @LogTable  (MasterID, UserID, LogDate, LogText)
        VALUES (2, 'CD', '08/11/2012', 'Client Visit') 
-- create table to display data
DECLARE @MyTemp TABLE (MasterID INT, Details VARCHAR(50), LogData1 VARCHAR(50), LogData2 VARCHAR(50), LogData3 VARCHAR(50))
INSERT INTO @MyTemp SELECT MasterID, Details, NULL, NULL, NULL FROM @MasterTable
-- create vars
DECLARE @ID INT, @NewID INT, @MasterID INT, @NewValue VARCHAR(100)
SET @ID = 0
-- loop through data
WHILE @ID >-1
BEGIN
    -- clear vars
    SELECT @NewID = NULL, @MasterID = NULL, @NewValue = NULL
    -- get first record
    SELECT TOP 1    
        @NewValue = CONVERT(VARCHAR(10), LogDate, 103)+ ' ' + UserID + ': ' + LogText
    ,   @MasterID=MasterID
    ,   @NewID=LogID 
    FROM @LogTable WHERE LogID>@ID
    -- if no data, exit loop
    IF @NewID IS NULL
        BREAK
    -- update record based on valuds in fields
    UPDATE m 
        SET @ID = @NewID
        ,   LogData1 = (CASE WHEN m.LogData1 IS NULL THEN @NewValue ELSE m.LogData1 END)
        ,   LogData2 = (CASE WHEN m.LogData1 IS NOT NULL THEN 
                            (CASE WHEN m.LogData2 IS NULL THEN @NewValue ELSE m.LogData2 END)
                        ELSE m.LogData2 END)
        ,   LogData3 = (CASE WHEN m.LogData1 IS NOT NULL THEN 
                            (CASE WHEN m.LogData2 IS NOT NULL THEN 
                                (CASE WHEN m.LogData3 IS NULL THEN @NewValue ELSE m.LogData3 END)
                             ELSE m.LogData3 END)
                        ELSE m.LogData3 END)
    FROM @MyTemp m
    WHERE m.MasterID=@MasterID
END
--display all data
SELECT * FROM @MyTemp 
于 2012-11-26T13:37:20.150 回答