SQL运算符作为where子句中的文本
我有下表,它是用来储存带子的。该表通过web前端进行维护SQL运算符作为where子句中的文本,sql,sql-server-2005,operators,case,Sql,Sql Server 2005,Operators,Case,我有下表,它是用来储存带子的。该表通过web前端进行维护 CREATE TABLE [dbo].[Banding]( [BandingID] [int] IDENTITY(1,1) NOT NULL, [ValueLowerLimitOperator] [varchar](10) NULL, [ValueLowerLimit] [decimal](9, 2) NULL, [ValueUpperLimitOperator] [varchar](10) NULL, [ValueUpperLimit]
CREATE TABLE [dbo].[Banding](
[BandingID] [int] IDENTITY(1,1) NOT NULL,
[ValueLowerLimitOperator] [varchar](10) NULL,
[ValueLowerLimit] [decimal](9, 2) NULL,
[ValueUpperLimitOperator] [varchar](10) NULL,
[ValueUpperLimit] [decimal](9, 2) NULL,
[VolumeLowerLimitOperator] [varchar](10) NULL
运算符字段存储值,例如><>=X END
而不是必须为每个排列编写多个case或if语句
有人对我如何解码存储在表中的运算符值(作为查询的一部分)并在case/where语句中使用它们有什么建议吗?您需要。没有更多的信息,但我不能给你更多的例子比在链接中你需要的。如果没有更多的信息,尽管我无法给出比链接中更多的示例,为什么不输入以下值: 1表示>,-1表示=,-2表示=0和abs(ValueLowerLimitOperator)>1) --这意味着它是=并且条件是真的。 或(值*值LowerLimitor-x*值LowerLimitor>0和abs(值LowerLimitor)=1) --这意味着它是<或>且条件为真。 或(值=x和值LowerLimitOperator=0) --这意味着它是=并且条件是真的。 那么1 结束
这样就可以了。为什么不输入以下值: 1表示>,-1表示=,-2表示=0和abs(ValueLowerLimitOperator)>1) --这意味着它是=并且条件是真的。 或(值*值LowerLimitor-x*值LowerLimitor>0和abs(值LowerLimitor)=1) --这意味着它是<或>且条件为真。 或(值=x和值LowerLimitOperator=0) --这意味着它是=并且条件是真的。 那么1 结束
这就可以了。有几种技巧,但有一些需要注意;试图将两种类型的功能压缩到一个查询中通常会导致执行计划不佳。(例如,表或索引扫描,而不是索引查找。) 我经常发现重新思考数据的设计和/或重新思考如何形成查询更好
回答你问题中的具体例子,我会这样做
WHERE
CASE WHEN VALUE < X THEN 1
WHEN VALUE = X THEN 2
WHEN VALUE > X THEN 4
END
|
CASE ValueLowerLimitOperator
WHEN '<' THEN 1
WHEN '<=' THEN 3
WHEN '=' THEN 2
WHEN '>=' THEN 6
WHEN '>' THEN 4
END
<>
0
由于您希望在LowerLimit、UpperLimit等中重复此操作,因此将其封装在函数中对我来说是个好主意。有几种技术,但有一些需要注意;试图将两种类型的功能压缩到一个查询中通常会导致执行计划不佳。(例如,表或索引扫描,而不是索引查找。) 我经常发现重新思考数据的设计和/或重新思考如何形成查询更好
回答你问题中的具体例子,我会这样做
WHERE
CASE WHEN VALUE < X THEN 1
WHEN VALUE = X THEN 2
WHEN VALUE > X THEN 4
END
|
CASE ValueLowerLimitOperator
WHEN '<' THEN 1
WHEN '<=' THEN 3
WHEN '=' THEN 2
WHEN '>=' THEN 6
WHEN '>' THEN 4
END
<>
0
正如您希望对LowerLimit、UpperLimit等重复此操作一样,将其封装到函数中对我来说是个好主意。感谢您的建议,是的,我可以这样做,但我更愿意避免它并使用静态SQL。感谢您的建议,是的,我可以这样做,但是我宁愿避免使用静态SQL;它需要
=
以及
…它可以解决。将状态更改为-2(),-1(=),并执行类似于value*operator-x*abs(operator)的操作,检查操作符的abs是否大于1,结果是否为0或相反。但我必须承认,这将使我的解决方案更加复杂。尽管如此,这仍然是一个解决方案…在你的答案中写下OP的完整解决方案:)如果它符合OP的要求,我会投票给你…谢谢Sara,你似乎在这里有所发现,但你能按照Dems的建议发布完整的解决方案吗?我一直在想这类事情,直到我读到问题;它需要=
以及
…它可以解决。将状态更改为-2(),-1(=),并执行类似于value*operator-x*abs(operator)的操作,检查操作符的abs是否大于1,结果是否为0或相反。但我必须承认,这将使我的解决方案更加复杂。尽管如此,这仍然是一个解决方案…在你的答案中写下OP的完整解决方案:)如果它符合OP的要求,我会投票给你…谢谢Sara,你似乎在这里找到了一些东西,但是你能像Dems建议的那样发布你的完整解决方案吗?
select *
from table
where 1=
case
when (value * ValueLowerLimitOperator -x*ValueLowerLimitOperator >=0 and abs(ValueLowerLimitOperator)>1)
--that means it is <= or >= and the condition is true.
or (value * ValueLowerLimitOperator -x*ValueLowerLimitOperator >0 and abs(ValueLowerLimitOperator)=1)
--that means it is < or > and the condition is true.
or (value =x and ValueLowerLimitOperator=0)
--that means it is = and the condition is true.
then 1
end
WHERE
CASE WHEN VALUE < X THEN 1
WHEN VALUE = X THEN 2
WHEN VALUE > X THEN 4
END
|
CASE ValueLowerLimitOperator
WHEN '<' THEN 1
WHEN '<=' THEN 3
WHEN '=' THEN 2
WHEN '>=' THEN 6
WHEN '>' THEN 4
END
<>
0
WHERE
CASE ValueLowerLimitOperator
WHEN '<' THEN CASE WHEN VALUE < X THEN 1 ELSE 0 END
WHEN '<=' THEN CASE WHEN VALUE <= X THEN 1 ELSE 0 END
WHEN '=' THEN CASE WHEN VALUE = X THEN 1 ELSE 0 END
WHEN '>=' THEN CASE WHEN VALUE >= X THEN 1 ELSE 0 END
WHEN '>' THEN CASE WHEN VALUE > X THEN 1 ELSE 0 END
END
=
1
WITH main_query AS (SELECT * FROM blah)
SELECT * FROM main_query WHERE ValueLowerLimitOperator = '<' AND VALUE < X
UNION ALL
SELECT * FROM main_query WHERE ValueLowerLimitOperator = '<=' AND VALUE <= X
UNION ALL
SELECT * FROM main_query WHERE ValueLowerLimitOperator = '=' AND VALUE = X
UNION ALL
SELECT * FROM main_query WHERE ValueLowerLimitOperator = '>=' AND VALUE >= X
UNION ALL
SELECT * FROM main_query WHERE ValueLowerLimitOperator = '>' AND VALUE > X
SELECT
*
FROM
main_query
CROSS APPLY
dbo.my_function(ValueLowerLimitOperator, VALUE, X) AS check
WHERE
check.return_value = 1
(Using CROSS APPLY with a Inline Table Valued Function will be MUCH faster than a Scalar Function in the WHERE clause)