2016-07-30 102 views
0

我有这个问题。让我们看看查询:针对主详细查询结果的SQL Server条件查询

SELECT 
    D.DocumentName, 
    D.Title, 
    D.Description, 
    V.Version, 
    CASE 
     WHEN V.State = 'PUB' THEN 'PUBLISHED' 
     WHEN V.State = 'UNP' THEN 'UNPUBLISHED' 
     WHEN V.State IS NULL THEN 'NOT PUBLISHED' 
     ELSE '' 
    END AS State 
FROM 
    Document D 
LEFT JOIN 
    DocumentVersion V ON D.IdDocument = V.IdDocumentVersion 

这是一个典型的主 - 细节表(Document-DocumentVersion)。 A Document可以有一个或多个DocumentVersions或没有。 A DocumentVersion状态可以是PUBLISHEDUNPUBLISHEDPUBLISHED一个DocumentVersion只能存在一次Document(这是由应用程序控制),但可以存在很多UNPUBLISHED,或者所有DocumentVersions都是UNPUBLISHED。 NOT PUBLISHED不存在,当Document没有DocumentVersion记录时,这只是查询结果中的一个单词,这就是LEFT JOIN的原因。

所以我的问题是:我如何使查询完成下一个规则?

  • 如果DocumentVersion状态PUB,忽略了别人,我的意思是不显示UNP那些在查询结果用于本Document

  • 如果DocumentVersion状态UNP(这里可许多UNP),那么只显示最高日期为UnpublishDocumentVersion表格有UnPublishDate列),此规则适用于没有PUBDocumentVersion的文档

我将不胜感激任何帮助,你可以给我,谢谢你们。

回答

0

这是一个优先级查询。您可以使用row_number()rank()做到这一点:

select d.*, dv.* 
from d left join 
    (select dv.*, 
      row_number() over (partition by dv.IdDocument 
           order by (case when dv.state = 'PUB' then 1 
               when dv.state = 'UNP' then 2 
               else 3 
              end) 
           ) as seqnum 
     from documentversion dv 
    ) dv 
    on dv.IdDocument = d.IdDocument and 
     seqnum = 1; 

注:我不认为加盟条件是你的问题是正确的。

+0

与您的方法'UNP'的显示状态的UnPublishedDate最低,我需要最高的一个,另外我需要的情况下,当DocumentVersion不是文档,因此我使用LEFT JOIN。 –

+0

哦,我认为Gordon刚刚错过了'UnPublishDate desc',并且需要做一个左外连接。我的查询几乎相同 –

+0

@VorpulusLyphane。 。 。谢谢。 –

1
select * 
from Document D 
left outer join 
    (select *, 
    row_number()over(partition by IdDocumentVersion order by state asc, UnPublishDate desc) as row 
    from DocumentVersion) V 
on D.IdDocument = V.IdDocumentVersion 
and V.row = 1 

State asc在刚才碰巧在这种情况下工作的方式有些破绽。你可能想更明确一个'什么时候'(见戈登的答案)。

+0

谢谢。添加了“UnPublishDate desc”与他制作和编辑的编辑(@Gordon),但我不明白一件事情,请查看我最后一次对@Gordon的评论。 –

+0

Gordon以某种方式设法正确地预测了DV表中IdDocument列的存在(此列出现在你的'正在工作'查询中的任何地方),并且信心十足,他实际上在他的答案中使用了它。我假设 - 错误地,事实证明 - 你简单地将代表文档ID的列命名为IDDocumentVersion。换句话说,这两个查询旨在通过相同的事物进行分区:DocumentID。您可以按DocumentID进行分区,以便对于每个DocumentID,您可以按优先顺序排列版本(PUB over UNP,然后再更早版本),并将其排在最前面。 –

+0

感谢您的帮助。 –