我认为自己对T-SQL非常熟练,而且我通常能够在不丢失可读性的情况下优化查询。简而言之:我喜欢我的SQL简洁,描述性,声明性和优雅。如何将以下代码转换为SQL Server/T-SQL CTE?
虽然下面的代码工作,我有两个问题是:
- 我使用游标,我不能动摇的感觉我在我的后脑勺,它本来可以做更多有效地使用CTE。另外游标不能在视图中工作,所以我不能在客户端或从属SQL中处理结果/范围。
- 该代码在存储过程中实现,导致与上面相同的问题。特别是使用LInQ进行SQL和自动分页。
因此,鉴于以下SP,有没有人看到任何明显的方式将此转换为使用递归CTE的普通选择?我试过了,失败了,我想我会看到堆栈溢出社区可能会提出什么。
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROC [dbo].[usp_GetLastReferers]
(
@Limit int = NULL
)
AS
BEGIN
SET NOCOUNT ON
CREATE TABLE #Referer
(
ID int,
Url nvarchar(500),
Referer nvarchar(500)
)
DECLARE @ID int
DECLARE @Url nvarchar(500)
DECLARE @Referer nvarchar(500)
DECLARE @Count int
SET @Count = 0
DECLARE LogCursor CURSOR FORWARD_ONLY READ_ONLY FOR
SELECT ID, Url, Referer FROM Log WHERE Referer <> '' ORDER BY ID DESC
OPEN LogCursor
FETCH NEXT FROM LogCursor INTO @ID, @Url, @Referer
WHILE @@FETCH_STATUS = 0 AND (@Count < @Limit OR @Limit IS NULL)
BEGIN
DECLARE @Hits int
SELECT @Hits = COUNT(*)
FROM #Referer
WHERE Referer = @Referer
DECLARE @IsLocal bit
SELECT @IsLocal = dbo.IsLocalSite(@Referer)
IF (@Hits = 0 OR @Hits IS NULL) AND @IsLocal = 0
BEGIN
INSERT INTO #Referer(ID,Url,Referer) VALUES (@ID,@Url,@Referer)
SET @Count = @Count + 1
END
FETCH NEXT FROM LogCursor INTO @ID, @Url, @Referer
END
CLOSE LogCursor
DEALLOCATE LogCursor
SELECT *
FROM #Referer
DROP TABLE #Referer
SET NOCOUNT OFF
END
由于它可能不是完全明显,我想在这里做的是类似于tothe下列准SQL
SELECT DISTINCT TOP(@Limit) ID, Url, Referer
FROM Log
ORDER BY ID DESC
基本上得到最后独特指(不是唯一的行) ,通常包含重复项,并按降序排列。这绝对是棘手的问题。
这些数据是非常简单的HTTP日志。 ID字段只是一个唯一的行标识符,Url是完整的url requesten,Referer是该请求的HTTP引用者。没有一个值可以为null,但引用者可以为空(即'')。 IsSiteLocal只是一个简单的过滤功能,用于排除源自我自己站点的引用者。
如果有人希望得到一些样本数据,我可以上传一个小型的数据库备份,这样你就可以得到一些东西。
抽样数据可以在这里找到: http://svada.kjonigsen.net/files/IISLogsDBBackup.zip
某些样本数据可能是? – 2010-09-22 11:42:58
尽管这比我的更重要,但它仍然不完全正确,或者不符合我的要求。下面的代码样本使用SQL烘烤成小的测试:DECLARE @Limit INT = 20 ; WITH查阅情况AS ( \t SELECT TOP(@Limit)l.Url,l.Referer,MAX(ID)AS' ID” \t FROM登录升 \t其中0 = dbo.IsLocalSite(l.Referer) \t AND l.Referer <> '' \t GROUP BY l.Url,l.Referer \t ORDER BY 3递减 ) ,JustReferers AS ( \t SELECT DISTINCT Referer \t FROM Referer (*) FROM JustReferers - != @Limit足够大的@Limit数量。将导致不正确的分页。 – 2010-09-22 13:04:36
你可以添加一些我们不需要下载的示例数据吗? – DForck42 2010-09-22 18:12:43