免责声明:我无法完全控制数据库模式,不要判断数据结构或命名约定:)
我正在使用多个连接进行这个大型查询:
SELECT TOP 30
iss.iss_lKey as IssueId,
iss.iss_sName as IssueName,
con.con_lKey as ContainerId,
con.con_sName as ContainerName,
sto.sto_lKey as StoryId,
sto.sto_sName as StoryName,
sto.sto_Guid as StoryGuid,
sto.sto_sByline as Byline,
sto.sto_created_dWhen as StoryCreatedDate,
sto.sto_deadline_dWhen as StoryDeadline,
sto.sto_lType as StoryType,
sto.sto_sct_lKey as StoryCategory,
sto.sto_created_use_lKey as CreatedBy,
sfv.sfv_tValue as FieldValue,
sf.sfe_lKey as StoryFieldId,
sf.sfe_sCaption as StoryFieldCaption,
sre.sre_lIndex as RevisionIndex
FROM tStory30 sto
JOIN tContainer30 con ON sto.sto_con_lKey = con.con_lKey
JOIN tIssue30 iss ON con.con_iss_lKey = iss.iss_lKey
LEFT OUTER JOIN tStoryRevision30 sre ON sre.sre_sto_lKey = sto.sto_lKey
LEFT OUTER JOIN tStoryField30 sf ON sre.sre_lKey = sf.sfe_sre_lKey
LEFT OUTER JOIN tStoryFieldValue30 sfv ON sfv.sfv_sfe_lKey= sf.sfe_lKey
WHERE sre.sre_lIndex = 0
AND (sto.sto_sName LIKE '%' + @0 + '%'
OR sfv.sfv_tValue LIKE '%' + @0 + '%')";
我需要的实际上只是 StoryId 的一行,其中包括匹配的 FieldValue(如果有的话)。我目前正在对代码进行分组以生成输出,但这使我无法对结果进行分页。
from r in items
group r by new { r.StoryId, r.ContainerId, r.IssueId }
into storyGroup
select {
storyGroup.Key.StoryId,
storyGroup.Key.ContainerId,
storyGroup.Key.IssueId,
Hits = storyGroup.ToList()
}
有什么方法可以在sql中实现这种分组,以便我可以正确地对结果进行分页(使用ROW_NUMBER() OVER)?
此外,我知道这是不好的做法,应该使用全文搜索。计划设置一个 solr 实例,或使用 sqlserver 中的全文选项。这是第一次尝试让事情顺利进行。
编辑
尝试口头解释我想要实现的目标:
就上下文而言,我们的应用程序是杂志编辑/出版商的CMS。
对于某本杂志,他们有很多问题
每期都有很多容器(某种逻辑文章组)
每个容器里都有几个故事
故事车有 0 次或多次修订
故事的字段按修订存储(每个修订有许多字段)
并且一个字段有一个字段值。
我需要检索在第一个修订的名称或字段值中具有给定文本的故事(即 revisionIndex = 0)。 但我还需要检索每个故事的相关数据。 (issueId、名称、containerId 和名称等等......) 困难的可能是检索与搜索匹配的字段值之一。我不需要全部,只需要一个...
希望这有帮助!
编辑搜索“test”的示例数据。我简化了列以使其更容易理解。
Row | IssueId | IssueName | ContainerId | StoryId | FieldValue
1 | 11 IssueName A 394 868 Test Marsupilami bla bla youpi
2 | 40 IssueName B 6 631 story save test
3 | 40 IssueName B 6 666 test story
4 | 4 IssueName c 30 846 test abs
5 | 4 IssueName c 30 846 absc test
6 | 4 IssueName c 30 846 hello test
我能够在查询中获取 sqlserver 中的行号,但是在这里,正如您所看到的,我多次得到相同的故事。在这种情况下,我可以得到以下简单的结果:
Row | IssueId | IssueName | ContainerId | StoryId | FieldValue
1 | 11 IssueName A 394 868 Test Marsupilami bla bla youpi
2 | 40 IssueName B 6 631 story save test
3 | 4 IssueName c 30 846 test abs
如果一个故事在故事名称中进行了测试,那么我可以接受 FieldValue 列中的空值,选择哪个字段值并不重要。
这是一个题外话,但您是否知道您已将左连接转换为内连接?
LEFT OUTER JOIN tStoryRevision30 sre ON sre.sre_sto_lKey = sto.sto_lKey
LEFT OUTER JOIN tStoryField30 sf ON sre.sre_lKey = sf.sfe_sre_lKey
LEFT OUTER JOIN tStoryFieldValue30 sfv ON sfv.sfv_sfe_lKey= sf.sfe_lKey
WHERE sre.sre_lIndex = 0
试试这个吧
LEFT OUTER JOIN tStoryRevision30 sre ON sre.sre_sto_lKey = sto.sto_lKey
AND sre.sre_lIndex = 0
LEFT OUTER JOIN tStoryField30 sf ON sre.sre_lKey = sf.sfe_sre_lKey
LEFT OUTER JOIN tStoryFieldValue30 sfv ON sfv.sfv_sfe_lKey= sf.sfe_lKey
(我会在评论中完成此操作,但在这里更容易看到代码更改。