Sql server 我为什么不';t使用;在X和Y之间“;在SQL中的varchar字段上返回数字?
我在一个表中有一个索引(但不是唯一的)员工ID的varchar字段,在一个查询中,我需要返回正好是4个数字字符但也超过1000的行 我在这里发现了关于使用验证方法检查字段是否包含0-9个字符,或不包含a-z字符等的各种问题,但这些问题与此问题无关 背景: 我得到了一个具有各种值的表,样本集如下:Sql server 我为什么不';t使用;在X和Y之间“;在SQL中的varchar字段上返回数字?,sql-server,where,where-clause,between,Sql Server,Where,Where Clause,Between,我在一个表中有一个索引(但不是唯一的)员工ID的varchar字段,在一个查询中,我需要返回正好是4个数字字符但也超过1000的行 我在这里发现了关于使用验证方法检查字段是否包含0-9个字符,或不包含a-z字符等的各种问题,但这些问题与此问题无关 背景: 我得到了一个具有各种值的表,样本集如下: EmployeeID ---------- 6745 EMP1 EMP2 1874 LTST 5694 0014 我想做的是返回除EMP1、EMP2、LTST和0014之外的所有值 我的问题是,有什么
EmployeeID
----------
6745
EMP1
EMP2
1874
LTST
5694
0014
我想做的是返回除EMP1
、EMP2
、LTST
和0014
之外的所有值
我的问题是,有什么理由我不应该使用Where子句,比如Where EmployeeID介于“1000”和“9999”之间
?之所以使用employeeid,是因为它是一个varchar列
如果我能做到这一点,我是否也应该按员工ID订购,或者这无关紧要?运行以下代码作为示例,您将看到SQL Server不会将
INT
视为存储为VARCHAR
的整数:
WITH IntsAsVars
AS (
SELECT var = '1000',
int = 1000
UNION ALL
SELECT var = '100',
int = 100
UNION ALL
SELECT var = '9999',
int = 999
UNION ALL
SELECT var = '99',
int = 99
UNION ALL
SELECT var = '750',
int = 750
UNION ALL
SELECT var = '10',
int = 10
UNION ALL
SELECT var = '2',
int = 2
)
SELECT *
FROM IntsAsVars
--WHERE var BETWEEN '2' AND '750'
/* should return 2, 10, 99, 100 & 750 if it works like INT
but does it? */
ORDER BY
--var ASC,
int ASC;
在没有WHERE子句的情况下运行它,因此SQLServer在被存储为VARCHAR时不认为其他记录在2到750之间:
运行以下代码作为示例,您将看到SQL Server不会将
INT
视为存储为VARCHAR
的整数:
WITH IntsAsVars
AS (
SELECT var = '1000',
int = 1000
UNION ALL
SELECT var = '100',
int = 100
UNION ALL
SELECT var = '9999',
int = 999
UNION ALL
SELECT var = '99',
int = 99
UNION ALL
SELECT var = '750',
int = 750
UNION ALL
SELECT var = '10',
int = 10
UNION ALL
SELECT var = '2',
int = 2
)
SELECT *
FROM IntsAsVars
--WHERE var BETWEEN '2' AND '750'
/* should return 2, 10, 99, 100 & 750 if it works like INT
but does it? */
ORDER BY
--var ASC,
int ASC;
在没有WHERE子句的情况下运行它,因此SQLServer在被存储为VARCHAR时不认为其他记录在2到750之间:
我相信在'1000'和'9999'之间的where子句中会省略“0014”,所以这是一个原因。也许介于“0000”和“9999”之间的更适合您的目的。请记住,您仍然在根据文本进行排序。如果您有任何类似“1_99”的条目,这也会显示在查询结果中,并带有给定的between子句
如果您希望只返回不包括前导零的4个字符的数字,那么以下加法就足够了:
WHERE EmployeeID BETWEEN '1000' AND '9999' AND TRY_CAST(EmployeeID As int) IS NOT NULL
…或者更直观地说:
WHERE TRY_CAST(EmployeeID As int) BETWEEN 1000 AND 9999
我相信在'1000'和'9999'之间的where子句中会省略“0014”,所以这是一个原因。也许介于“0000”和“9999”之间的更适合您的目的。请记住,您仍然在根据文本进行排序。如果您有任何类似“1_99”的条目,这也会显示在查询结果中,并带有给定的between子句
如果您希望只返回不包括前导零的4个字符的数字,那么以下加法就足够了:
WHERE EmployeeID BETWEEN '1000' AND '9999' AND TRY_CAST(EmployeeID As int) IS NOT NULL
…或者更直观地说:
WHERE TRY_CAST(EmployeeID As int) BETWEEN 1000 AND 9999
如果实际数据与以字母开头的非数字值的示例数据完全相同,则可以使用查询来获得所需的结果
但是,请注意数据的排序顺序。如果您的EmployeeId为1ABC
,它将包含在返回的数据中,其中EmployeeId介于“1000”和“9999”之间。
您的方法不适合过滤非数值
附加的ORDER BY
仅影响结果的顺序,它对WHERE
条件的计算没有影响。如果实际数据与以字母开头的非数字值的样本数据完全相同,则可以使用查询来获得所需的结果
但是,请注意数据的排序顺序。如果您的EmployeeId为1ABC
,它将包含在返回的数据中,其中EmployeeId介于“1000”和“9999”之间。
您的方法不适合过滤非数值
附加的排序依据
仅影响结果的顺序,它对WHERE
条件的评估没有影响。我想说最简单的方法是使用如下方法:
select * from yourtable
where EmployeeID like '[1-9][0-9][0-9][0-9]'
我想说,最简单的方法是使用:
select * from yourtable
where EmployeeID like '[1-9][0-9][0-9][0-9]'
假设您有以下输入:
IF OBJECT_ID('tempdb..#test') IS NOT NULL
DROP TABLE #test
CREATE TABLE #test
(
EmployeeID VARCHAR(255)
)
CREATE CLUSTERED INDEX CIX_test_EmployeeID ON #test(EmployeeID)
INSERT INTO #test
VALUES
('6745'),
('EMP1'),
('EMP2'),
('1874'),
('LTST'),
('5694'),
('1000'),
('9999'),
('10L'),
('187'),
('9X9'),
('7est'),
('1ok'),
('0_o'),
('0014');
您的语句还将返回“1ok”、“187”、“10L”等。
既然您提到您的employeeID有一个固定的长度,您可以使用如下内容:
SELECT *
FROM #test
WHERE EmployeeID LIKE '[1-9][0-9][0-9][0-9]'
假设您有以下输入:
IF OBJECT_ID('tempdb..#test') IS NOT NULL
DROP TABLE #test
CREATE TABLE #test
(
EmployeeID VARCHAR(255)
)
CREATE CLUSTERED INDEX CIX_test_EmployeeID ON #test(EmployeeID)
INSERT INTO #test
VALUES
('6745'),
('EMP1'),
('EMP2'),
('1874'),
('LTST'),
('5694'),
('1000'),
('9999'),
('10L'),
('187'),
('9X9'),
('7est'),
('1ok'),
('0_o'),
('0014');
您的语句还将返回“1ok”、“187”、“10L”等。
既然您提到您的employeeID有一个固定的长度,您可以使用如下内容:
SELECT *
FROM #test
WHERE EmployeeID LIKE '[1-9][0-9][0-9][0-9]'
返回除EMP1、EMP2、LTST和0014之外的所有值。这是什么原因?你可以像你在问题中说的那样做中间人。你的问题是什么facing@TheGameiswar我的问题是,是否有理由不以这种方式使用“between”,也就是说,当我们读取它们时,它是否会返回非数字的意外结果?返回除EMP1、EMP2、LTST和0014之外的所有值。这是什么原因?你可以像你在问题中说的那样做中间人。你的问题是什么facing@TheGameiswar我的问题是,是否有理由我不应该以这种方式使用“between”(介于两者之间),即它是否会在我们读取它们时返回非数字的意外结果是的,我希望0014
被忽略。在本例中,我只希望varchar值实际上是数字,实际上是4个字符,不包括任何前导零。我担心的是像1_99
这样的值。是的,我希望0014
被忽略。在本例中,我只希望varchar值实际上是数字,实际上是4个字符,不包括任何前导零。我担心的是像1\u99
这样的值,谢谢你的回答。我的场景不会看到这个问题,因为我也处理固定长度的字符。这很公平,但这会阻止像“0001”这样的值吗?'0011'? 等等?谢谢你的回答。我的场景不会看到这个问题,因为我处理的是固定长度字符