Sql server 从SQL生成类似excel的报告
我是SQL和SQL的新手 我有两个表Ticket和TicketAttributes,其模式如下Sql server 从SQL生成类似excel的报告,sql-server,Sql Server,我是SQL和SQL的新手 我有两个表Ticket和TicketAttributes,其模式如下 CREATE TABLE [dbo].[Ticket]( [TicketID] [int] IDENTITY(1,1) NOT NULL, --Primary key [Category] [varchar](256) NOT NULL, [Description] [varchar](256) NULL, [LibID] [int] NOT NULL, [Status]
CREATE TABLE [dbo].[Ticket](
[TicketID] [int] IDENTITY(1,1) NOT NULL, --Primary key
[Category] [varchar](256) NOT NULL,
[Description] [varchar](256) NULL,
[LibID] [int] NOT NULL,
[Status] [smallint] NULL,
[LogID] [int] NULL)
票证属性
CREATE TABLE [dbo].[TicketAttributes](
[TicketID] [int] NOT NULL,
[TicketAttrID] [int] IDENTITY(1,1) NOT NULL,
[AttributeID] [int] NOT NULL,
[AttributeGroup] [varchar](255) NULL,
[AttributeValue] [nvarchar](max) NULL,
[Status] [smallint] NULL,
[LogID] [int] NULL)
其中Ticket Attribute是另一个存储TicketStatus、TicketCategory等不同属性的表。。
现在我需要生成一个如下所示的报告
TicketStatus1 TicketStatus 2 TicketStatus3
-----------------------------------------------------------------
TicketCategory1 7 3
Ticketcategory2 4
TicketCategory3 8
我想查看每个票证类别的每个状态的计数。
例如:-
我在票务表中有以下数据
----------------------------------------------
TicketID Name Price Date
------------------------------------------------
155 Ticket4 $20 16 Jan 2016
157 Ticket3 $300 17 Jan 2016
158 Ticket1 $100 18 Jan 2016
159 Ticket2 $500 19 Jan 2016
现在在TicketAttribute表中
----------------------------------------------
TicketID AttributeID AttributeValue
------------------------------------------------
155 500 Joe
155 600 Reserved
155 700 Economy
155 800 San Jose
他在哪里
500=Nameofthe Passenger
600= Status of Ticket
700= Class
800= Destination
现在让我们假设我想看看每个类中每个状态的活动票证数量是多少
Booked Cancelled PaymentPending ............
-----------------------------------------------------------------
Economy 7 3
Economy Plus 4
Business 8
希望我现在明白了。
如何使用PIVOT使用SQL查询执行此操作
;WITH cte AS (
SELECT
c.AttributeValue as Class
,s.AttributeValue as StatusOfTicket
FROM
Ticket t
LEFT JOIN TicketAttributes c
ON t.TicketId = c.TicketId
AND c.AttributeID = 700
LEFT JOIN TicketAttributes s
ON t.TicketId = s.TicketId
AND s.AttributeID = 600
)
SELECT *
FROM
cte
PIVOT (
COUNT(StatusOfTicket) FOR StatusOfTicket IN (Reserved,Cancelled,PaymentPending)
) p
使用条件聚合:
SELECT
c.AttributeValue as Class
,COUNT(DISTINCT CASE WHEN s.AttributeValue = 'Reserved' THEN c.TicketId END) as Reserved
,COUNT(DISTINCT CASE WHEN s.AttributeValue = 'Cancelled' THEN c.TicketId END) as Cancelled
,COUNT(DISTINCT CASE WHEN s.AttributeValue = 'PaymentPending' THEN c.TicketId END) as PaymentPending
FROM
Ticket t
LEFT JOIN TicketAttributes c
ON t.TicketId = c.TicketId
AND c.AttributeID = 700
LEFT JOIN TicketAttributes s
ON t.TicketId = s.TicketId
AND s.AttributeID = 600
GROUP BY
c.AttributeValue
使用枢轴
;WITH cte AS (
SELECT
c.AttributeValue as Class
,s.AttributeValue as StatusOfTicket
FROM
Ticket t
LEFT JOIN TicketAttributes c
ON t.TicketId = c.TicketId
AND c.AttributeID = 700
LEFT JOIN TicketAttributes s
ON t.TicketId = s.TicketId
AND s.AttributeID = 600
)
SELECT *
FROM
cte
PIVOT (
COUNT(StatusOfTicket) FOR StatusOfTicket IN (Reserved,Cancelled,PaymentPending)
) p
使用条件聚合:
SELECT
c.AttributeValue as Class
,COUNT(DISTINCT CASE WHEN s.AttributeValue = 'Reserved' THEN c.TicketId END) as Reserved
,COUNT(DISTINCT CASE WHEN s.AttributeValue = 'Cancelled' THEN c.TicketId END) as Cancelled
,COUNT(DISTINCT CASE WHEN s.AttributeValue = 'PaymentPending' THEN c.TicketId END) as PaymentPending
FROM
Ticket t
LEFT JOIN TicketAttributes c
ON t.TicketId = c.TicketId
AND c.AttributeID = 700
LEFT JOIN TicketAttributes s
ON t.TicketId = s.TicketId
AND s.AttributeID = 600
GROUP BY
c.AttributeValue
把结果改成文本显示而不是网格显示怎么样?是的,任何东西都可以。但是我的主要问题是如何开始为此编写查询。你能发布你的查询以及一些示例数据吗?刚刚发布,请检查并让我知道您是否需要更多信息我肯定看不到结果如何显示为与数据透视相关的文本………如何更改结果以文本形式而不是网格形式显示是的,任何东西都可以。但我的主要问题是如何开始为此编写查询。你能发布你的查询以及一些示例数据吗?刚刚发布,请检查并让我知道你是否需要更多信息。我肯定看不到如何将结果显示为与数据透视相关的文本………如果TicketStatus的值如保留、取消、,PaymentPending是动态的。也就是说,它们不是预定义的,而是作为AttributeValue存储在Table@Programmerzzz我猜有一些有限的状态?在保持动态的情况下,您将动态地查找Status will和的不同值,然后修改此SQL并执行动态sql@Programmerzzz谢谢,第二个看起来不错,但你能帮我理解吗that@Programmerzzz两者都会起作用,对于这两种情况,您都需要创建一个包含多个列的表,1个列表示类,1个列表示状态。要做到这一点,您需要两次将票据连接到属性表。如果缺少属性,请使用左连接。然后,您只需进行聚合。对于SUM()、MAX()、COUNT()等聚合,它们都会忽略空值,因此在不满足条件时,通过使用case表达式删除值,然后进行聚合,您可以限制对该条件的项目进行计数。如果ticketstatus(如Reserved、Cancelled、PaymentPending)的值是动态的,该怎么办。也就是说,它们不是预定义的,而是作为AttributeValue存储在Table@Programmerzzz我猜有一些有限的状态?在保持动态的情况下,您将动态地查找Status will和的不同值,然后修改此SQL并执行动态sql@Programmerzzz谢谢,第二个看起来不错,但你能帮我理解吗that@Programmerzzz两者都会起作用,对于这两种情况,您都需要创建一个包含多个列的表,1个列表示类,1个列表示状态。要做到这一点,您需要两次将票据连接到属性表。如果缺少属性,请使用左连接。然后,您只需进行聚合。对于SUM()、MAX()、COUNT()等聚合,它们都将忽略空值,因此,当不满足条件时,通过使用case表达式删除值,然后对其进行聚合,可以限制对该条件的项进行计数。