实际上,您可以通过多种方式存储数据,但不同之处在于您呈现数据的方式。
在您的情况下,您希望在行列中显示数据,您也可以在代码端进行设计。
重点是如何存储数据。
为此,您可以通过为部门及其相关消息创建不同的表作为“部门”和“部门消息详细信息”来以规范化的形式存储数据。
或者您也可以将其以非规范化形式存储在单个表中。
在做报告时。您可以使用动态 SQL 脚本创建一个存储过程并在那里设计您的表。
示例:
DECLARE @Department TABLE
(
DNAM NVARCHAR(100),
DNO INT
)
INSERT INTO @Department
( DNAM, DNO )
VALUES ( N'D1', 1),
( N'D2', 2),
( N'D3', 3)
DECLARE @Message TABLE
(
DNO INT,
[D1] NVARCHAR(100),
[D2] NVARCHAR(100),
[D3] NVARCHAR(100)
)
INSERT INTO @Message
( DNO, D1, D2, D3 )
VALUES ( 1, N'T1_D1', N'T1_D2', N'T1_D3')--, ( 1, N'Test3 D2')
,( 1, N'', N'Test1 D1', N'')
,( 1, N'T1_D1', N'', N'')
,( 1, N'', N'T1_D2', N'')
,( 1, N'', N'', N'T1_D3')
,( 1, N'', N'', N'T1_D3')
,( 2, N'T2_D1', N'T2_D2', N'T2_D3')--, ( 2, N'Test3 D2')
,( 2, N'T2_D1', N'', N'')
,( 2, N'', N'T2_D2', N'')
,( 2, N'', N'', N'T2_D3')
,( 2, N'', N'', N'T2_D3')
,( 2, N'', N'', N'T2_D3')
,( 3, N'T3_D1', N'T3_D2', N'T3_D3')--, ( 3, N'Test3 D3')
,( 3, N'T3_D1', N'', N'')
,( 3, N'', N'T3_D2', N'')
,( 3, N'', N'', N'T3_D3')
SELECT * FROM @Department
SELECT * FROM @Message
;WITH T AS
(
SELECT DISTINCT
(CASE WHEN DNO = 1 THEN 'D1'
WHEN DNO = 2 THEN 'D2'
WHEN DNO = 3 THEN 'D3'
END) AS Names
, DNO
FROM
@Message
)
SELECT
T1.Names ,
(CASE
WHEN T1.Names = 'D1' THEN -1
WHEN T1.Names = 'D2' THEN (SELECT COUNT(*) FROM @Message M WHERE (M.DNO = 1) AND (ISNULL(M.D2, '') <> ''))
ELSE (SELECT COUNT(*) FROM @Message M WHERE (M.DNO = 1) AND (ISNULL(M.D3, '') <> ''))
END) AS D1 ,
(CASE WHEN T1.Names = 'D2' THEN -1
WHEN T1.Names = 'D1' THEN (SELECT COUNT(*) FROM @Message M WHERE (M.DNO = 2) AND (ISNULL(M.D1, '') <> ''))
ELSE (SELECT COUNT(*) FROM @Message M WHERE (M.DNO = 2) AND (ISNULL(M.D3, '') <> ''))
END) AS D2 ,
(CASE WHEN T1.Names = 'D3' THEN -1
WHEN T1.Names = 'D2' THEN (SELECT COUNT(*) FROM @Message M WHERE (M.DNO = 3) AND (ISNULL(M.D2, '') <> ''))
ELSE (SELECT COUNT(*) FROM @Message M WHERE (M.DNO = 3) AND (ISNULL(M.D1, '') <> ''))
END) AS D3
FROM T T1
在这个示例中,我使用了硬编码的列名,但是如果我们编写动态查询也可以处理,我稍后会跳过。