这是设置,问题如下。
CREATE TABLE Person (
PersonId int Identity(1,1) not null,
PersonName varchar(20) not null
PRIMARY KEY CLUSTERED (PersonId)
)
GO
CREATE TABLE Size (
SizeId int IDENTITY (1,1) not null,
Size varchar(20) null,
PersonId int NOT NULL
PRIMARY KEY CLUSTERED (SizeId)
)
ALTER TABLE dbo.Size
ADD CONSTRAINT FK_Size_Person FOREIGN KEY (PersonId) REFERENCES dbo.Person (PersonId)
GO
INSERT INTO Person (PersonName)
VALUES ('Bob'), ('Bill'), ('Dave'), ('Nathan'), ('Luke')
GO
INSERT INTO Size (Size, PersonId)
VALUES ('32', 1), ('2XL', 1), ('Large', 1), ('Small', 2), ('Medium', 3)
CREATE FUNCTION [dbo].[fn_Sizes]
(
@PersonId int
)
RETURNS varchar(150)
AS
BEGIN
DECLARE @sizes varchar(150)
SET @sizes = (SELECT s.Size + ', '
FROM dbo.Size s
WHERE s.PersonId = @PersonId
FOR XML PATH(''))
-- Return the sizes
RETURN ISNULL(LEFT(@sizes, LEN(@sizes)-1),'')
END
修复视图,其中一个问题是将多行值组合到一列中的函数。我不确定问题是DISTINCT关键字,函数,FOR XML PATH的使用,还是所有问题。我正在优化一个需要15分钟才能运行的视图,执行计划表示90%的工作都在DISTINCT排序中。所以我正在寻找摆脱它的方法。
实际的视图查询非常大,但本节的一个示例是:
SELECT DISTINCT p.PersonName, dbo.fn_Sizes(p.PersonId) as Size
FROM dbo.Person p
JOIN dbo.Size s ON p.PersonId = s.PersonId
DISTINCT在那里摆脱额外的Bob行,因为Bob有很多尺寸。我需要在Bob的行上保留多个大小,但我不想要多行Bob。除了使用DISTINCT之外,还有更有效的方法吗?
其次,街上的一句话是,如果你想要速度,最好避免使用这些功能。我没有看到在函数外部使用“FOR XML PATH”的方法,因为我不能让它只在一列上工作。所以我正在寻找一种在一行上产生多个值的方法。