我有下面的数据结构。基本上我允许用户(我的团队的可信成员)创建一个预定义的查询来对一组数据运行。他们可以指定表名,数据库,分类字段(基本上是GROUP BY)和聚合值字段。因为查询可以包含任意数量的分类字段和任意数量的值字段,所以我制作了一个非常复杂的模型来存储所有这些字段。您可以运行以下脚本来创建模型并插入一些记录。然后从视图[rpt]。[vwQueryStatsDetail]中选择*以获得结果的样本。
我的问题是 - 如何显示结果翻转另一个方向以显示,例如,“人员密钥”,“总支付金额”和“记录计数”作为标题和这些列的所有值?我在想某种支点,但我还没有运气。我试图在单个SQL语句中获取它并避免动态SQL或将自己限制在单个报告层(如SSRS等)。
编辑:查看我放在一起的SQL Fiddle示例。对于大多数人来说比运行下面的所有脚本更容易。 http://sqlfiddle.com/#!3/7d0e4/4
谢谢!
=============================================== ===============================
CREATE SCHEMA di
GO
CREATE SCHEMA rpt
GO
CREATE TABLE [di].[ClientQuery](
[ClientQueryID] [int] IDENTITY(1,1) NOT NULL,
[QueryID] [int] NOT NULL,
[DBListID] [int] NOT NULL,
[RecordTimestamp] [datetime] NOT NULL,
[Active] [bit] NULL,
PRIMARY KEY CLUSTERED
(
[ClientQueryID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [di].[Query](
[QueryID] [int] IDENTITY(1,1) NOT NULL,
[Description] [varchar](100) NOT NULL,
[TableNameMatchPattern] [varchar](100) NOT NULL,
[RecordTimestamp] [datetime] NOT NULL,
[Active] [bit] NULL,
PRIMARY KEY CLUSTERED
(
[QueryID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [di].[QueryCategoryField](
[QueryCategoryFieldID] [int] IDENTITY(1,1) NOT NULL,
[QueryID] [int] NOT NULL,
[Expression] [varchar](800) NOT NULL,
[Description] [varchar](800) NOT NULL,
[Ordinal] [int] NOT NULL,
[RecordTimestamp] [datetime] NOT NULL,
PRIMARY KEY CLUSTERED
(
[QueryCategoryFieldID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [di].[QueryInstance](
[QueryInstanceID] [int] IDENTITY(1,1) NOT NULL,
[ClientQueryID] [int] NOT NULL,
[RecordTimestamp] [datetime] NOT NULL,
PRIMARY KEY CLUSTERED
(
[QueryInstanceID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [di].[QueryInstanceRecord](
[QueryInstanceRecordID] [int] IDENTITY(1,1) NOT NULL,
[QueryInstanceID] [int] NOT NULL,
[RecordTimestamp] [datetime] NOT NULL,
[TableName] [varchar](100) NULL,
PRIMARY KEY CLUSTERED
(
[QueryInstanceRecordID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [di].[QueryInstanceRecordCategory](
[QueryInstanceRecordCategoryID] [int] IDENTITY(1,1) NOT NULL,
[QueryInstanceRecordID] [int] NOT NULL,
[QueryCategoryFieldID] [int] NOT NULL,
[Value] [varchar](100) NULL,
[RecordTimestamp] [datetime] NOT NULL,
PRIMARY KEY CLUSTERED
(
[QueryInstanceRecordCategoryID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [di].[QueryInstanceRecordValue](
[QueryInstanceRecordValueID] [int] IDENTITY(1,1) NOT NULL,
[QueryInstanceRecordID] [int] NOT NULL,
[QueryValueFieldID] [int] NOT NULL,
[Value] [decimal](19, 6) NULL,
[RecordTimestamp] [datetime] NOT NULL
) ON [PRIMARY]
GO
CREATE TABLE [di].[QueryValueField](
[QueryValueFieldID] [int] IDENTITY(1,1) NOT NULL,
[QueryID] [int] NOT NULL,
[Expression] [varchar](800) NOT NULL,
[Description] [varchar](800) NOT NULL,
[Ordinal] [int] NOT NULL,
[AggregationType] [varchar](20) NOT NULL,
[HavingValue] [varchar](100) NULL,
[RecordTimestamp] [datetime] NOT NULL,
PRIMARY KEY CLUSTERED
(
[QueryValueFieldID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [di].[ClientQuery] ON
GO
INSERT [di].[ClientQuery] ([ClientQueryID], [QueryID], [DBListID], [RecordTimestamp], [Active]) VALUES (1, 1, 81, CAST(0x0000A2C9010BCA28 AS DateTime), NULL)
GO
INSERT [di].[ClientQuery] ([ClientQueryID], [QueryID], [DBListID], [RecordTimestamp], [Active]) VALUES (2, 2, 18, CAST(0x0000A2CA00A5FFCA AS DateTime), 1)
GO
SET IDENTITY_INSERT [di].[ClientQuery] OFF
GO
SET IDENTITY_INSERT [di].[Query] ON
GO
INSERT [di].[Query] ([QueryID], [Description], [TableNameMatchPattern], [RecordTimestamp], [Active]) VALUES (1, N'PersonKey excessive count', N'tblMiningCache^_^_[1-9]%^_^_P^_[1-2][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]', CAST(0x0000A2C9010BB343 AS DateTime), NULL)
GO
INSERT [di].[Query] ([QueryID], [Description], [TableNameMatchPattern], [RecordTimestamp], [Active]) VALUES (2, N'Unique EID values', N'tblMembers_EligibiltyHistoryLatest', CAST(0x0000A2CA00A5B3FF AS DateTime), 1)
GO
SET IDENTITY_INSERT [di].[Query] OFF
GO
SET IDENTITY_INSERT [di].[QueryCategoryField] ON
GO
INSERT [di].[QueryCategoryField] ([QueryCategoryFieldID], [QueryID], [Expression], [Description], [Ordinal], [RecordTimestamp]) VALUES (1, 1, N'PersonKey', N'Person Key', 1, CAST(0x0000A2C9010BE0F2 AS DateTime))
GO
INSERT [di].[QueryCategoryField] ([QueryCategoryFieldID], [QueryID], [Expression], [Description], [Ordinal], [RecordTimestamp]) VALUES (3, 2, N'TapeID', N'Tape ID', 1, CAST(0x0000A2CA00A6A711 AS DateTime))
GO
SET IDENTITY_INSERT [di].[QueryCategoryField] OFF
GO
SET IDENTITY_INSERT [di].[QueryInstance] ON
GO
INSERT [di].[QueryInstance] ([QueryInstanceID], [ClientQueryID], [RecordTimestamp]) VALUES (1, 1, CAST(0x0000A2CA00999F0D AS DateTime))
GO
INSERT [di].[QueryInstance] ([QueryInstanceID], [ClientQueryID], [RecordTimestamp]) VALUES (2, 2, CAST(0x0000A2CA00A6DF1A AS DateTime))
GO
SET IDENTITY_INSERT [di].[QueryInstance] OFF
GO
SET IDENTITY_INSERT [di].[QueryInstanceRecord] ON
GO
INSERT [di].[QueryInstanceRecord] ([QueryInstanceRecordID], [QueryInstanceID], [RecordTimestamp], [TableName]) VALUES (1, 1, CAST(0x0000A2CA009D65B3 AS DateTime), N'tblMiningCache__123__P_2014-01-30')
GO
INSERT [di].[QueryInstanceRecord] ([QueryInstanceRecordID], [QueryInstanceID], [RecordTimestamp], [TableName]) VALUES (2, 1, CAST(0x0000A2CA009D6609 AS DateTime), N'tblMiningCache__123__P_2014-01-30')
GO
INSERT [di].[QueryInstanceRecord] ([QueryInstanceRecordID], [QueryInstanceID], [RecordTimestamp], [TableName]) VALUES (3, 2, CAST(0x0000A2CA00A70FA5 AS DateTime), N'tblMembers_EligibilityHistoryLatest')
GO
INSERT [di].[QueryInstanceRecord] ([QueryInstanceRecordID], [QueryInstanceID], [RecordTimestamp], [TableName]) VALUES (4, 2, CAST(0x0000A2CA00A84356 AS DateTime), N'tblMembers_EligibilityHistoryLatest')
GO
SET IDENTITY_INSERT [di].[QueryInstanceRecord] OFF
GO
SET IDENTITY_INSERT [di].[QueryInstanceRecordCategory] ON
GO
INSERT [di].[QueryInstanceRecordCategory] ([QueryInstanceRecordCategoryID], [QueryInstanceRecordID], [QueryCategoryFieldID], [Value], [RecordTimestamp]) VALUES (1, 1, 1, N'ABC999123', CAST(0x0000A2CA009A5638 AS DateTime))
GO
INSERT [di].[QueryInstanceRecordCategory] ([QueryInstanceRecordCategoryID], [QueryInstanceRecordID], [QueryCategoryFieldID], [Value], [RecordTimestamp]) VALUES (2, 2, 1, N'DEF123888', CAST(0x0000A2CA009A64A5 AS DateTime))
GO
INSERT [di].[QueryInstanceRecordCategory] ([QueryInstanceRecordCategoryID], [QueryInstanceRecordID], [QueryCategoryFieldID], [Value], [RecordTimestamp]) VALUES (3, 3, 1, N'ZZ801999A', CAST(0x0000A2CA009A7CAF AS DateTime))
GO
INSERT [di].[QueryInstanceRecordCategory] ([QueryInstanceRecordCategoryID], [QueryInstanceRecordID], [QueryCategoryFieldID], [Value], [RecordTimestamp]) VALUES (5, 3, 3, N'1370', CAST(0x0000A2CA00A81EE4 AS DateTime))
GO
INSERT [di].[QueryInstanceRecordCategory] ([QueryInstanceRecordCategoryID], [QueryInstanceRecordID], [QueryCategoryFieldID], [Value], [RecordTimestamp]) VALUES (6, 4, 3, N'1015', CAST(0x0000A2CA00A8AC47 AS DateTime))
GO
SET IDENTITY_INSERT [di].[QueryInstanceRecordCategory] OFF
GO
SET IDENTITY_INSERT [di].[QueryInstanceRecordValue] ON
GO
INSERT [di].[QueryInstanceRecordValue] ([QueryInstanceRecordValueID], [QueryInstanceRecordID], [QueryValueFieldID], [Value], [RecordTimestamp]) VALUES (1, 1, 1, CAST(1001.000000 AS Decimal(19, 6)), CAST(0x0000A2CA009AAA6F AS DateTime))
GO
INSERT [di].[QueryInstanceRecordValue] ([QueryInstanceRecordValueID], [QueryInstanceRecordID], [QueryValueFieldID], [Value], [RecordTimestamp]) VALUES (2, 2, 1, CAST(1500.000000 AS Decimal(19, 6)), CAST(0x0000A2CA009BB3B9 AS DateTime))
GO
INSERT [di].[QueryInstanceRecordValue] ([QueryInstanceRecordValueID], [QueryInstanceRecordID], [QueryValueFieldID], [Value], [RecordTimestamp]) VALUES (3, 3, 1, CAST(9000.000000 AS Decimal(19, 6)), CAST(0x0000A2CA009BCC7E AS DateTime))
GO
INSERT [di].[QueryInstanceRecordValue] ([QueryInstanceRecordValueID], [QueryInstanceRecordID], [QueryValueFieldID], [Value], [RecordTimestamp]) VALUES (4, 1, 2, CAST(1000000.000000 AS Decimal(19, 6)), CAST(0x0000A2CA00A13E8F AS DateTime))
GO
INSERT [di].[QueryInstanceRecordValue] ([QueryInstanceRecordValueID], [QueryInstanceRecordID], [QueryValueFieldID], [Value], [RecordTimestamp]) VALUES (5, 2, 2, CAST(55123.000000 AS Decimal(19, 6)), CAST(0x0000A2CA00A1493A AS DateTime))
GO
INSERT [di].[QueryInstanceRecordValue] ([QueryInstanceRecordValueID], [QueryInstanceRecordID], [QueryValueFieldID], [Value], [RecordTimestamp]) VALUES (6, 3, 3, CAST(99123945.000000 AS Decimal(19, 6)), CAST(0x0000A2CA00A15541 AS DateTime))
GO
INSERT [di].[QueryInstanceRecordValue] ([QueryInstanceRecordValueID], [QueryInstanceRecordID], [QueryValueFieldID], [Value], [RecordTimestamp]) VALUES (7, 4, 3, CAST(90210.000000 AS Decimal(19, 6)), CAST(0x0000A2CA00AA4535 AS DateTime))
GO
SET IDENTITY_INSERT [di].[QueryInstanceRecordValue] OFF
GO
SET IDENTITY_INSERT [di].[QueryValueField] ON
GO
INSERT [di].[QueryValueField] ([QueryValueFieldID], [QueryID], [Expression], [Description], [Ordinal], [AggregationType], [HavingValue], [RecordTimestamp]) VALUES (1, 1, N'LineKeyID', N'Record Count', 1, N'COUNT', N'>1000', CAST(0x0000A2C9010C12F7 AS DateTime))
GO
INSERT [di].[QueryValueField] ([QueryValueFieldID], [QueryID], [Expression], [Description], [Ordinal], [AggregationType], [HavingValue], [RecordTimestamp]) VALUES (2, 1, N'PayAmount', N'Total Pay Amount', 2, N'SUM', NULL, CAST(0x0000A2CA00A05245 AS DateTime))
GO
INSERT [di].[QueryValueField] ([QueryValueFieldID], [QueryID], [Expression], [Description], [Ordinal], [AggregationType], [HavingValue], [RecordTimestamp]) VALUES (3, 2, N'DISTINCT EID', N'Unique Employee ID Count', 1, N'COUNT', NULL, CAST(0x0000A2CA00A6510F AS DateTime))
GO
SET IDENTITY_INSERT [di].[QueryValueField] OFF
GO
ALTER TABLE [di].[ClientQuery] ADD DEFAULT (getdate()) FOR [RecordTimestamp]
GO
ALTER TABLE [di].[ClientQuery] ADD DEFAULT ((1)) FOR [Active]
GO
ALTER TABLE [di].[Query] ADD DEFAULT (getdate()) FOR [RecordTimestamp]
GO
ALTER TABLE [di].[Query] ADD DEFAULT ((1)) FOR [Active]
GO
ALTER TABLE [di].[QueryCategoryField] ADD DEFAULT (getdate()) FOR [RecordTimestamp]
GO
ALTER TABLE [di].[QueryInstance] ADD DEFAULT (getdate()) FOR [RecordTimestamp]
GO
ALTER TABLE [di].[QueryInstanceRecord] ADD DEFAULT (getdate()) FOR [RecordTimestamp]
GO
ALTER TABLE [di].[QueryInstanceRecordCategory] ADD DEFAULT (getdate()) FOR [RecordTimestamp]
GO
ALTER TABLE [di].[QueryInstanceRecordValue] ADD DEFAULT (getdate()) FOR [RecordTimestamp]
GO
ALTER TABLE [di].[QueryValueField] ADD DEFAULT (getdate()) FOR [RecordTimestamp]
GO
CREATE VIEW [rpt].[vwQueryStatsDetail]
AS SELECT cdb.ID as ClientID,
q.QueryID,
q.Description AS QueryDescription,
cq.ClientQueryID,
qir.TableName,
qir.QueryInstanceRecordID,
qcf.Description AS CategoryDescription,
qirc.Value AS CategoryValue,
qvf.Description AS NumericValueDescription,
qirv.Value AS NumericValue,
qi.RecordTimestamp AS QueryInstanceDateTime
FROM di.Query AS q JOIN di.ClientQuery AS cq ON q.QueryID = cq.QueryID
JOIN di.QueryInstance AS qi ON qi.ClientQueryID = cq.ClientQueryID
JOIN di.QueryInstanceRecord AS qir ON qir.QueryInstanceID = qi.QueryInstanceID
JOIN di.QueryInstanceRecordCategory AS qirc ON qirc.QueryInstanceRecordID = qir.QueryInstanceRecordID
JOIN di.QueryInstanceRecordValue AS qirv ON qirv.QueryInstanceRecordID = qir.QueryInstanceRecordID
JOIN dbo.vwClientDatabases AS cdb ON cq.DBListID = cdb.Id
JOIN di.QueryCategoryField AS qcf ON qcf.QueryCategoryFieldID = qirc.QueryCategoryFieldID
AND qcf.QueryID = q.QueryID
JOIN di.QueryValueField AS qvf ON qvf.QueryValueFieldID = qirv.QueryValueFieldID
AND qvf.QueryID = q.QueryID
GO