分享
 
 
 

SQLServer2005Beta2Transact-SQL功能(3)

王朝mssql·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

在开放架构方案中,您需要用事先不知道或因实体类型而异的属性集来维护实体。应用程序的用户动态定义这些属性。您将属性拆分到不同的行中,并且只为每个实体实例存储相关的属性,而不是在表中预定义很多列并存储很多空值。

PIVOT 使您可以为开放架构和其他需要将行旋转为列的方案生成交叉分析报表,并且可能同时计算聚合并且以有用的形式呈现数据。

开放架构方案的一个示例是跟踪可供拍卖的项目的数据库。某些属性与所有拍卖项目有关,例如,项目类型、项目的制造日期以及它的初始价格。只有与所有项目有关的属性被存储在 AuctionItems 表中:

CREATE TABLE AuctionItems

(

itemid

INT

NOT NULL PRIMARY KEY NONCLUSTERED,

itemtype

NVARCHAR(30) NOT NULL,

whenmade

INT

NOT NULL,

initialprice MONEY

NOT NULL,

/* other columns */

)

CREATE UNIQUE CLUSTERED INDEX idx_uc_itemtype_itemid

ON AuctionItems(itemtype, itemid)

INSERT INTO AuctionItems VALUES(1, N'Wine',

1822,

3000)

INSERT INTO AuctionItems VALUES(2, N'Wine',

1807,

500)

INSERT INTO AuctionItems VALUES(3, N'Chair',

1753,

800000)

INSERT INTO AuctionItems VALUES(4, N'Ring',

-501,

1000000)

INSERT INTO AuctionItems VALUES(5, N'Painting', 1873,

8000000)

INSERT INTO AuctionItems VALUES(6, N'Painting', 1889,

8000000)

其他属性特定于项目类型,并且不同类型的新项目被不断地添加。这样的属性可以存储在不同的 ItemAttributes 表中,其中每个项属性都存储在不同的行中。每个行都包含项目 ID、属性名称和属性值:

CREATE TABLE ItemAttributes

(

itemid

INT

NOT NULL REFERENCES AuctionItems,

attribute NVARCHAR(30) NOT NULL,

value

SQL_VARIANT

NOT NULL,

PRIMARY KEY (itemid, attribute)

)

INSERT INTO ItemAttributes

VALUES(1, N'manufacturer', CAST(N'ABC'

AS NVARCHAR(30)))

INSERT INTO ItemAttributes

VALUES(1, N'type',

CAST(N'Pinot Noir'

AS NVARCHAR(15)))

INSERT INTO ItemAttributes

VALUES(1, N'color',

CAST(N'Red'

AS NVARCHAR(15)))

INSERT INTO ItemAttributes

VALUES(2, N'manufacturer', CAST(N'XYZ'

AS NVARCHAR(30)))

INSERT INTO ItemAttributes

VALUES(2, N'type',

CAST(N'Porto'

AS NVARCHAR(15)))

INSERT INTO ItemAttributes

VALUES(2, N'color',

CAST(N'Red'

AS NVARCHAR(15)))

INSERT INTO ItemAttributes

VALUES(3, N'material',

CAST(N'Wood'

AS NVARCHAR(15)))

INSERT INTO ItemAttributes

VALUES(3, N'padding',

CAST(N'Silk'

AS NVARCHAR(15)))

INSERT INTO ItemAttributes

VALUES(4, N'material',

CAST(N'Gold'

AS NVARCHAR(15)))

INSERT INTO ItemAttributes

VALUES(4, N'inscription',

CAST(N'One ring ...'

AS NVARCHAR(50)))

INSERT INTO ItemAttributes

VALUES(4, N'size',

CAST(10

AS INT))

INSERT INTO ItemAttributes

VALUES(5, N'artist',

CAST(N'Claude Monet'

AS NVARCHAR(30)))

INSERT INTO ItemAttributes

VALUES(5, N'name',

CAST(N'Field of Poppies' AS NVARCHAR(30)))

INSERT INTO ItemAttributes

VALUES(5, N'type',

CAST(N'Oil'

AS NVARCHAR(30)))

INSERT INTO ItemAttributes

VALUES(5, N'height',

CAST(19.625

AS NUMERIC(9,3)))

INSERT INTO ItemAttributes

VALUES(5, N'width',

CAST(25.625

AS NUMERIC(9,3)))

INSERT INTO ItemAttributes

VALUES(6, N'artist',

CAST(N'Vincent Van Gogh' AS NVARCHAR(30)))

INSERT INTO ItemAttributes

VALUES(6, N'name',

CAST(N'The Starry Night' AS NVARCHAR(30)))

INSERT INTO ItemAttributes

VALUES(6, N'type',

CAST(N'Oil'

AS NVARCHAR(30)))

INSERT INTO ItemAttributes

VALUES(6, N'height',

CAST(28.75

AS NUMERIC(9,3)))

INSERT INTO ItemAttributes

VALUES(6, N'width',

CAST(36.25

AS NUMERIC(9,3)))

请注意,sql_variant 数据类型被用于 value 列,因为不同的属性值可能具有不同的数据类型。例如,size 属性存储整数属性值,而 name 属性存储字符串属性值。

假设您希望呈现 ItemAttributes 表中的数据,该表具有与每个油画项目(项目 5、6)相对应的行以及与每个属性相对应的列。如果没有 PIVOT 运算符,则必须编写如下所示的查询:

SELECT

itemid,

MAX(CASE WHEN attribute = 'artist'

THEN value END) AS [artist],

MAX(CASE WHEN attribute = 'name'

THEN value END) AS [name],

MAX(CASE WHEN attribute = 'type'

THEN value END) AS [type],

MAX(CASE WHEN attribute = 'height'

THEN value END) AS [height],

MAX(CASE WHEN attribute = 'width'

THEN value END) AS [width]

FROM ItemAttributes AS ATR

WHERE itemid IN(5,6)

GROUP BY itemid

以下为结果集:

itemid artist

name

type

height width

------ ---------------- ---------------- ---------- ------ ------

5

Claude Monet

Field of Poppies Oil

19.625 25.625

6

Vincent Van Gogh The Starry Night Oil

28.750 36.250

PIVOT 运算符使您可以维护更简短且更可读的代码以获得相同的结果:

SELECT *

FROM ItemAttributes AS ATR

PIVOT

(

MAX(value)

FOR attribute IN([artist], [name], [type], [height], [width])

) AS PVT

WHERE itemid IN(5,6)

像大多数新功能一样,对 PIVOT 运算符的理解来自于试验和使用。PIVOT 语法中的某些元素是显而易见的,并且只需要您弄清楚这些元素与不使用新运算符的查询之间的关系。其他元素则是隐藏的。

您可能会发现下列术语能够帮助您理解 PIVOT 运算符的语义:

table_expression

PIVOT 运算符所作用于的虚拟表(查询中位于 FROM 子句和 PIVOT 运算符之间的部分):在该示例中为 ItemAttributes AS ATR。

pivot_column

table_expression 中您希望将其值旋转为结果列的列:在该示例中为 attribute。

column_list

pivot_column 中您希望将其呈现为结果列的值列表(在 IN 子句前面的括号中)。它们必须表示为合法的标识符:在该示例中为 [artist]、[name]、[type]、[height]、[width]。

aggregate_function

用于生成结果中的数据或列值的聚合函数:在该示例中为 MAX()。

value_column

table_expression 中的用作 aggregate_function 的参数的列:在该示例中为 value。

group_by_list

隐藏的部分 ― table_expression 中除 pivot_column 和 value_column 以外所有用来对结果进行分组的列:在该示例中为 itemid。

select_list

SELECT 子句后面的列列表,可能包括 group_by_list 和 column_list 中的任何列。别名可以用来更改结果列的名称:* 在该示例中,返回 group_by_list 和 column_list 中的所有列。

PIVOT 运算符为 group_by_list 中的每个唯一值返回一个行,就好像您的查询带有 GROUP BY 子句并且您指定了这些列一样。请注意,group_by_list 是隐含的;它没有在查询中的任何位置显式指定。它包含 table_expression 中除 pivot_column 和 value_column 以外的所有列。理解这一点可能是理解您用 PIVOT 运算符编写的查询按照它们本身的方式工作以及在某些情况下可能获得错误的原因的关键。

可能的结果列包括 group_by_list 和 中的值。如果您指定星号 (*),则查询会返回这两个列表。结果列的数据部分或结果列值是通过将 value_column 用作参数的 aggregate_function 计算的。

下面的用各种颜色突出显示的代码说明了使用 PIVOT 运算符的查询中的不同元素:

SELECT * -- itemid, [artist], [name], [type], [height], [width]

FROM ItemAttributes AS ATR

PIVOT

(

MAX(value)

FOR attribute IN([artist], [name], [type], [height], [width])

) AS PVT

WHERE itemid IN(5,6)

以下代码将不同的元素与不使用 PIVOT 运算符的查询相

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有