1

我正在编写一个带有排名算法的搜索例程,并希望一次性完成。

我的理想查询将是这样的......

select *, (select top 1 wordposition
           from wordpositions
           where recordid=items.pk_itemid and wordid=79588 and nextwordid=64502
          ) as WordPos,
      case when WordPos<11 then 1 else case WordPos<50 then 2 else case WordPos<100 then 3 else 4 end end end end as rank
from items 

是否可以在那里使用 WordPos?它在我身上产生一个错误,列名“WordPos”无效。

我知道我可以为每个案例重做子查询,但我认为它实际上会重新运行案例,不是吗?

例如:

select *, case when (select top 1 wordposition from wordpositions where recordid=items.pk_itemid and wordid=79588 and nextwordid=64502)<11 then 1 else case (select top 1 wordposition from wordpositions where recordid=items.pk_itemid and wordid=79588 and nextwordid=64502)<50 then 2 else case (select top 1 wordposition from wordpositions where recordid=items.pk_itemid and wordid=79588 and nextwordid=64502)<100 then 3 else 4 end end end end as rank from items 

那行得通....但它真的每次都重新运行相同的查询吗?

很难从测试中分辨出来,因为它第一次运行很慢,但随后的运行很快......它正在缓存......所以这是否意味着它第一次运行它的第一行,随后的 3 次会从缓存中得到结果吗?

只是好奇最好的方法是什么......谢谢!瑞安

4

2 回答 2

1

您可以使用子查询来执行此操作。我会坚持你的 SQL Server 语法,即使问题被标记为 mysql:

select i.*,
       (case when WordPos < 11 then 1
             when WordPos < 50 then 2
             when WordPos < 100 then 3
        else 4
        end) as rank
from (select i.*,
             (select top 1 wpwordposition
              from wordpositions wp
              where recordid=i.pk_itemid and wordid=79588 and nextwordid=64502
             ) as WordPos
      from items i
     ) i;

这也简化了case语句。您不需要嵌套的 case 语句来处理多个条件,只需要多个where子句。

于 2013-11-01T22:40:55.073 回答
0

不可以。在输出子句中引入的标识符(它来自子查询的事实无关紧要)不能在同一个 SELECT 语句中使用。

以下是一些解决方案:

  1. 使用 JOIN 1重写查询,这将完全消除问题并且非常适合 RA。
  2. 将整个 SELECT 与子查询包装在另一个带有案例的 SELECT 中。外部选择可以访问由内部 SELECT 的输出子句引入的标识符。
  3. 使用 CTE(如果是 SQL Server)。这类似于#2,因为它允许引入标识符。

虽然“重写”每个案例的子查询非常混乱,但它仍然应该产生一个等效的计划 - 但查看查询配置文件!- 因为查询的结果是非易失的。因此,查询规划器可以安全地移动等效的子查询,它应该将子查询/子查询移动到 JOIN 以避免任何“重新运行”。


1这是使用 JOIN 的转换,这是我的首选方法。(我发现如果不能“轻松”地用 JOIN 来编写查询,那么它可能会要求错误的内容,或者显示架构设计存在问题。)

select
   wp.wordposition as WordPos,
   case wp.wordposition .. as Rank
from items i
left join wordpositions wp
  on wp.recordid = i.pk_itemid
where wp.wordid = 79588
  and wp.nextwordid = 64502

我已经对这里的多样性(即是唯一的)做出了假设,wordid这应该得到验证。如果这种多重性无效且无法纠正(并且您确实在使用 SQL Server),那么我建议使用ROW_NUMBER()and 一个 CTE。

于 2013-11-01T22:34:42.660 回答