如何在SQL中的varchar和数字值的组合之间进行搜索?

时间:2018-06-21 18:19:12

标签: sql sql-server

所以,我知道这是不好的数据库设计,但是不幸的是,这是我必须用于工作的内容,并且我正在努力弄清这一点。

我正在编写一个SQL查询,用于检查某个字段的值是否在两个值之间。

Select * 
from TestTable 
where TestField between ValueA and ValueB

唯一的问题是ValueA和ValueB以及TestField可以是整数或varchars。它们可以是100或X100之类的东西。以X开头的值大于没有X的任何整数。

因此,如果ValueA为100而ValueB为2000,我想返回Testfield在100和2000之间的所有行。

但是,如果ValueA为100,ValueB为X500,我想返回所有大于100的整数,以及所有以X开头且尾随数字小于500的值。

例如,顺序从最小到最大:

1. 100
2. 500
3. 1000
4. 5000
5. X100
6. X500
7. X1000
8. X2000

因此,对于我的问题:如何编写一个在ValueA和ValueB之间准确搜索的查询?

使用valueA和valueB作为varchars,这使我无法准确检查哪个数字更大。

2 个答案:

答案 0 :(得分:1)

我认为在C#的应用程序端处理WHERE子句的构建是一个好主意。

sqlstring="SELECT * FROM table WHERE ";

If (Regex.Matches(yourstring2,@"[a-zA-Z]").Count > 0) {
    sqlstring=sqlstring + " testfield > @param1a OR testfield BETWEEN @param2a AND param2b"
} else {
    sqlstring=sqlstring + " testfield BETWEEN @param1 AND @param2"
}

然后您可以使用类似的逻辑进行绑定

yourstring1=500;
yourstring2="x5000";

If (Regex.Matches(yourstring2,@"[a-zA-Z]").Count > 0) {
    command.Parameters.Add("@param1a", SqlDbType.Int);
    command.Parameters["@param1a"].Value = yourstring1;        

    command.Parameters.Add("@param2a", SqlDbType.Varchar);
    command.Parameters["@param2a"].Value = yourstring2.substring(1,1) + "0";
    command.Parameters.Add("@param2b", SqlDbType.Varchar);
    command.Parameters["@param2b"].value = yourstring2;
} else {

    command.Parameters.Add("@param1", SqlDbType.Int);
    command.Parameters["@param1"].Value = yourstring1;

    command.Parameters.Add("@param2", SqlDbType.Int);
    command.Parameters["@param2"].value = yourstring2;
}

我的C#充其量是生锈的,因此我100%确信这里的语法已经关闭,并且有一种更优雅的编写方式,但是...要点是相同的。编程语言感觉像是执行此操作的正确位置,而不是可能使用 的SQL,但这确实很丑陋,并且容易出错。在C#中,我们拥有所需的所有信息以及SQL方面缺少的许多细微差别的控制。

那是由于有人批评人们试图在应用程序方面做应该在数据库中完成的事情而引起的。

答案 1 :(得分:1)

这应该做到:

DECLARE
@Test TABLE
    (
         TestField VARCHAR(10)
    );

INSERT INTO
    @Test (TestField)
VALUES
    ('100'), ('500'), ('1000'), ('X10'), ('X500'), ('X3')
;

SELECT
     TestField
FROM
    @Test
ORDER BY
     CASE
         WHEN LEFT(TestField, 1) = 'X'
             THEN 1
         ELSE 0
     END
    ,CAST(REPLACE(TestField, 'X', '') AS INTEGER)

基本上,您首先要根据其是否以“ X”开头进行排序,然后删除“ X”并按其整数值对其进行排序。