Bri*_*hak 6 sql-server view functions
我正在和一位同事讨论解决问题的方法。
我们有一个表来跟踪填充过程,该表在列Lot和上具有唯一的索引列(或至少应该) TestGrade。
最近,我们添加了逻辑,以便当TestGrade创建大于 1 的任何值时,所有较低级别都会被创建。完成了一些逻辑,因此较低级别的行不一定与顶层相同。
例如,我插入一些东西Lot='ABCD',TestGrade=5然后在我的Fills表中我看到
id Lot TestGrade OtherColumns
======================================
10 'ABCD' 1 blah3
9 'ABCD' 2 bar
8 'ABCD' 3 foo
7 'ABCD' 4 blah1
6 'ABCD' 5 blah
Run Code Online (Sandbox Code Playgroud)
现在的问题是在许多情况下,我只想要 Fills 表的顶级记录,因此在示例中,我只想要带有id=6.
关于如何做到这一点,我们有两个想法。我想做一个看起来像
CREATE VIEW [dbo].[vwFills]
AS
SELECT t.* FROM [dbo].[Fills] t
JOIN (SELECT [Lot], MAX(TestGrade) as TestGrade FROM dbo.Fills GROUP BY [Lot]) t2 ON t.[Lot] = t2.[Lot] AND t.[TestGrade] = t2.[TestGrade]
Run Code Online (Sandbox Code Playgroud)
我的同事想做类似的事情,但在一个看起来像这样的函数内
ALTER FUNCTION [dbo].[fnFills] (
@Fills tyFills READONLY
)
RETURNS @returnTable TABLE(
//Copy of the table definition of Fills, without
id INT NOT NULL,
Lot VARCHAR(10) NOT NULL,
TestGrade INT NOT NULL,
//rest of the columns..
)
AS
Begin
insert into @returnTable
select t2.* from (
select [Lot], max([TestGrade]) as TestGrade from @Fills) t1
left join Fills t2
on t1.[Lot] = t2.[Lot] and t1.[TestGrade] = t2.[TestGrade]
Return
End
Run Code Online (Sandbox Code Playgroud)
然后调用这个函数,它看起来像
DECALARE @FillRecords tyFills;
INSERT INTO @FillRecords SELECT * FROM db.Fills;
SELECT * FROM dbo.fnFills(@FillRecords);
Run Code Online (Sandbox Code Playgroud)
我们确实在和dbo.Fills上有索引。然而,我的直觉是,使用插入变量然后将其提供给函数的函数方法,我们会丢失这些索引,因此通过此连接,我们将看到 O(n^2) 性能。这是一个公平的评价吗?我担心性能,因为服务器的硬件并不强大,因此任何有助于查询执行的东西都是首选。LotTestGrade
一般来说,在这种情况下,是否有最佳实践方法——视图或函数是“显而易见的”还是更好的选择?
你的直觉是对的。风景就是必经之路。该函数除了简单的 SELECT 语句之外不执行任何其他操作,根本不涉及过程逻辑。
也可以使用函数,但最好将其定义为内联表值函数:
CREATE FUNCTION dbo.fnFills()
RETURNS TABLE
RETURN(
SELECT t.*
FROM [dbo].[Fills] t
JOIN (SELECT [Lot], MAX(TestGrade) as TestGrade FROM dbo.Fills GROUP BY [Lot]) t2 ON t.[Lot] = t2.[Lot] AND t.[TestGrade] = t2.[TestGrade]
);
Run Code Online (Sandbox Code Playgroud)
这里很好地解释了表值函数和内联表值函数之间的区别。
但在这种情况下,该函数并没有比视图有任何优势,所以我会坚持使用良好的旧视图。
注意:我按原样接受了您的查询,但避免使用“SELECT *”语句被认为是最佳实践。