SQL Server:从没有排序列的临时结果中选择从x到y的范围

时间:2013-06-07 08:25:36

标签: tsql sql-server-2012

我的SQL Server数据库真的很奇怪,从昨天起就一直在搜索......但我现在必须放弃。

我有一个

  • Document表(DocumentID (PK), ArchiveNo等等...)

  • LanguageVersion table(LanguageVersionID (PK), LanguageVersionID (FK), ReleaseDate, Language,etc ...)与Document的关系为n:1(1 Document has(n)LanguageVersions)。

用户搜索后,我已经有一个允许用户查看的Document列表。 这些必须按ReleaseDate排序,LanguageVersion位于LanguageVersion表格中。

所以我加入了Document,自然导致ReleaseDate条目的重复,按DocumentID对结果进行排序,并切断除DocumentID以外的所有内容。

好的 - 到目前为止,我按正确的顺序得到了ROW_NUMBER()-OVER()的列表,但是有重复的。

现在要显示结果,要求是按照20 !! Documents !!的页面对这些结果进行分组。因此,我找到了两种可能的解决方案:ORDER-BY子句或SQL Server 2012中OFFSET子句的新扩展名为FETCH NEXTReleaseDate

问题是,这两个都需要一个排序列来生成行号作为范围选择的基础。

  • 如果我将DocumentID保留在此排序的临时结果中,则DocumentID的区别将失败,因为ReleaseDates的每个副本都有不同ReleaseDate }。

  • 如果我切断DISTINCT,我可以执行LIMIT但会丢失排序列以生成范围索引。

我很沮丧,因为我已经习惯了MySQL,在没有任何排序的情况下使用DISTINCT子句没有问题。

SQL Server中没有任何等价物吗?

我已经按正确的顺序获得了文档结果,唯一的问题是重复。 我想要的只是:DocumentID在{{1}}上,然后从中选择从x到y的范围。

提前问候并表示感谢, 克里斯

1 个答案:

答案 0 :(得分:0)

根据您的设置,您可以执行以下操作:

  • 创建一个CTE(公用表表达式)来选择DocumentID - 一次10个,每个20个 - 对你有用。这使您能够指定您想要的数量和DocumentID

  • 使用DocumentID表格加入CTE(限于所需的20 LanguageVersion页面),以获取您想要的完整数据集

这可以为您提供所需内容:定义并获取n DocumentID(用于分页),以及LanguageVersion表中的所有其他详细信息。

所以试试这个:

-- define the CTE, give it a name
;WITH DocumentPage AS
(
    -- define the rows to fetch - here, I'm using the ROW_NUMBER approach 
    SELECT 
        DocumentID ,
        ArchiveNo,
        RowNum = ROW_NUMBER() OVER(ORDER BY DocumentID)
    FROM dbo.Document
)
-- define the full query - get everything from the "paged" DocumentPage CTE,
-- plus the relevant details from the LanguageVersion table
SELECT  
    dp.DocumentID ,
    dp.ArchiveNo,
    lv.LanguageVersionID ,
    lv.ReleaseDate ,
    lv.Language
FROM 
    DocumentPage dp
INNER JOIN 
    dbo.LanguageVersion lv ON dp.DocumentID = lv.DocumentID
WHERE 
    dp.RowNum BETWEEN 51 AND 60 -- define which rows from the Document table you want