2

我有一个 SQL 查询,它将定价表连接到包含用户提供的答案的表。我的查询用于根据输入的数量获取价格。下面是我的 SQL 语句:

SELECT JobQuestion.Value, Price.Min, Price.Max, Price.Amount FROM Price
    INNER JOIN JobQuestion 
        ON Price.QuestionFK=JobQuestion.QuestionFK
        AND JobQuestion.JobFK=1
WHERE Price.Min <= JobQuestion.Value 
    AND Price.Max >= JobQuestion.Value

问题是 SQL Server 在 JOIN 之前运行 where 子句并抛出错误:

将 varchar 值“TEST”转换为数据类型 int 时转换失败。

因为它在连接之前进行了最小和最大比较('TEST' 是 JobQuestion 表中用户输入的有效值,但不应在 JobQuestion 连接到 Price 时返回)。我相信 SQL Server 选择运行 WHERE 是因为由于某种原因解析器认为这将是一个更有效的查询。如果我只是跑

SELECT JobQuestion.Value, Price.Min, Price.Max, Price.Amount FROM Price
    INNER JOIN JobQuestion 
        ON Price.QuestionFK=JobQuestion.QuestionFK
        AND JobQuestion.JobFK=1

我得到了这些结果:

500 1       500     272.00
500 501     1000    442.00
500 1001    2000    782.00

因此,添加 WHERE 应该过滤掉最后两个并只返回第一条记录。如何强制 SQL 先运行 JOIN 或使用另一种技术过滤掉我需要的记录?

4

6 回答 6

4

尝试“重新措辞”查询,如下所示:

SELECT *
FROM   (
          SELECT JobQuestion.Value, 
                 Price.Min, 
                 Price.Max, 
                 Price.Amount 
          FROM   Price
          INNER 
          JOIN   JobQuestion 
                 ON Price.QuestionFK = JobQuestion.QuestionFK
                 AND JobQuestion.JobFK = 1
       ) SQ
WHERE  SQ.Min <= SQ.Value 
AND    SQ.Max >= SQ.Value

根据 Christian Hayter 的回答,如果您有选择,请更改桌子设计 =)

于 2009-10-29T14:33:00.783 回答
2

您不应该将字符串与整数进行比较。如果您对表格设计有任何影响,那么将列的两种不同用途JobQuestion.Value分成两个不同的列。

于 2009-10-29T14:26:18.150 回答
1

首先,这很可能是设计不佳的标志。
如果您无法更改架构,那么也许您可以使用 hints强制执行此行为。引用:

提示是 SQL Server 查询处理器在 SELECT、INSERT、UPDATE 或 DELETE 语句上为强制执行而指定的选项或策略。提示会覆盖查询优化器可能为查询选择的任何执行计划。

还有更多:

警告:
因为 SQL Server 查询优化器通常会为查询选择最佳执行计划,我们建议只有经验丰富的开发人员和数据库管理员在不得已的情况下才使用 <join_hint>、<query_hint> 和 <table_hint>。

于 2009-10-29T14:33:54.323 回答
0

如果您对表格设计没有影响 - 您可以尝试使用ISNUMERIC ()过滤掉那些带有数值的记录吗?我猜想将此添加到您的 where 子句中可能会有所帮助。

于 2009-10-29T14:32:39.223 回答
0

您可能会删除 where... 并将它们作为谓词添加到您的联接中。由于它是内部连接,因此应该可以

SELECT JobQuestion.Value, Price.Min, Price.Max, Price.Amount 
FROM Price    
INNER JOIN JobQuestion
ON Price.QuestionFK=JobQuestion.QuestionFK       
AND JobQuestion.JobFK=1
AND Price.Min <= JobQuestion.Value
AND Price.Max >= JobQuestion.Value
于 2009-10-29T14:39:28.687 回答
0

您可以在该字符串列上使用 TRY_PARSE 将其转换为数字,如果 SQL 无法转换,它将为您提供 NULL 而不是错误消息。

PS 这个东西是 SQL 2012 中第一次引入,所以可能会有所帮助。

于 2013-01-22T14:56:25.720 回答