我在SQL Server 2000数据库中有以下表格:
主
MasterID | Details | [other fields]
=====================================
PK (int) | Free text | ...
LogTable
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列数据。
提前致谢。
答案 0 :(得分: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