我正在尝试编写一个sql查询,用于对2列进行字符串操作。
所以基本上目标是,对于2个不同列的值,如果数字的长度相同且两个符号相反,我必须从左边开始放下无关紧要的数字。这是一个帮助它变得清晰的例子。
如果我有2个数字,比方说1123457和-1124678,则查询应该返回3457和-4678。我有一个函数来做到这一点,但它似乎永远需要,因为那是逐行进行字符串操作。有没有人有这方面的经验?如果是这样,你能帮忙吗?
由于
答案 0 :(得分:0)
您可以使用ABS功能代替用空字符串替换“ - ”吗?我觉得这样会更快。
https://docs.microsoft.com/en-us/sql/t-sql/functions/abs-transact-sql
答案 1 :(得分:0)
首先,在决定编写一些复杂逻辑时,您需要找出可用的工具。处理数字的字符串操作应该会引起所有语言的代码异味警报。
您可以在此处阅读各种SQL Server功能: https://docs.microsoft.com/en-us/sql/t-sql/functions/mathematical-functions-transact-sql
您还可以在互联网上搜索解决方案。我不得不搜索“sql server查找数字中的位数”来查找这篇文章: Counting the number of digits in column
代码:
DECLARE @Sample TABLE ( Num1 INT, Num2 INT )
INSERT INTO @Sample
VALUES( 1123457, -1124678 ), ( -1223457, 1124678 ), ( -1223457, -1124678 ), ( 0, 0 )
;WITH Step1 AS(
-- Determine Number properties
SELECT Num1, Num2, ABS( Num1 ) AS Num1Abs, ABS( Num2 ) AS Num2Abs,
SIGN( Num1 ) AS Num1Sign,
SIGN( Num2 ) AS Num2Sign,
( CASE WHEN LEN( ABS( Num1 )) = LEN( ABS( Num2 )) THEN 1 ELSE 0 END ) AS LenMatchFlag
FROM @Sample
),
Step2 AS(
-- Find all possible significant digit matches of two numbers
SELECT Num1, Num2, Num1Abs, Num2Abs, Num1Sign, Num2Sign, NumDigits,
ROW_NUMBER() OVER( PARTITION BY Num1Abs, Num2Abs ORDER BY NumDigits ASC ) AS BestMatch
FROM Step1
-- Possible number of significant digits
CROSS JOIN (VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9)) AS NumLengths(NumDigits)
WHERE
LenMatchFlag = 1
AND Num1Sign = Num2Sign * -1 AND Num1Sign <> 0
AND ROUND( Num1Abs, -NumDigits, 1 ) = ROUND( Num2Abs, -NumDigits, 1 )
),
Step3 AS(
-- Return the best match, and calculate outpu values
SELECT (( Num1Abs - ROUND( Num1Abs, -NumDigits, 1 )) * Num1Sign ) AS NewNum1,
(( Num2Abs - ROUND( Num2Abs, -NumDigits, 1 )) * Num2Sign ) AS NewNum2,
*
FROM Step2
WHERE BestMatch = 1
)
SELECT 'Changed', NewNum1, NewNum2, Num1, Num2
FROM Step3
UNION ALL
SELECT 'UnChanged', Num1, Num2, Num1, Num2
FROM Step1
WHERE NOT(
LenMatchFlag = 1
AND Num1Sign = Num2Sign * -1 AND Num1Sign <> 0
)
输出:
NewNum1 NewNum2 Num1 Num2
--------- ----------- ----------- ----------- -----------
Processed 3457 -4678 1123457 -1124678
Processed -223457 124678 -1223457 1124678
UnChanged -1223457 -1124678 -1223457 -1124678
UnChanged 0 0 0 0
注意:如果您的号码超过9位,则需要向NumLengths
列表中添加更多值
注2:要查看每个计算步骤返回的值,您可以更改上一个SELECT
以返回特定的表格,例如SELECT * FROM Step1