sql - 从 SQL 数据实现 ELSE 表达式,可能吗?

标签 sql sql-server

假设有 2 个表,数据如下:

-- Table #Detail
TelNO      
---------- 
001xxxxx
020xxxxx
021xxxxx
800xxxxx
400xxxxx
28011111
82188888
22223333
...
...

-- Table #FeeRate
Expression Price   Description                                        
---------- ------- -------------------------------------------------- 
001%       10.00   International call
0[^0]%     5.00    National call
800%       .00     Free call
400%       .80     800 like, but caller need pay for local part
ELSE,How?  .20     Others/Local call

我想从按 dbo.FUNCTION_Match (TelNO, Expression) 条件连接的 2 个表中选择数据。 (dbo.FUNCTION_Match 是我编写的一个粗略函数,用于匹配 TelNOExpression。在此示例中,您可以将其视为 TelNO LIKE 表达式)。

所以SQL&查询结果是

SELECT * FROM #Detail d
    LEFT JOIN #FeeRate f ON d.TelNO LIKE f.Expression

TelNO      Expression Price   Description                                        
---------- ---------- ------- -------------------------------------------------- 
001xxxxx   001%       10.00   International call
020xxxxx   0[^0]%     5.00    National call
021xxxxx   0[^0]%     5.00    National call
800xxxxx   800%       .00     Free call
400xxxxx   400%       .80     800 like, but caller need pay for local part
28011111   NULL       NULL    NULL
82188888   NULL       NULL    NULL
22223333   NULL       NULL    NULL

问题很明显,#Detail 中的本地调用无法匹配 Others FeeRate。

我的原始 FUNCTION_Match 函数已处理多个表达式,例如 TelNO NOT LIKE '0%' AND TelNO NOT LIKE [84]00% OR TelNO LIKE '0755%' 来匹配 Others FeeRate,但是当 #FeeRate 表中有很多记录时,很难编写正确的多重表达式来表达 ELSE

那么,有没有办法从数据中实现ELSE表达式?

<小时/>

用于创建示例数据的 SQL

CREATE TABLE #Detail (TelNO VARCHAR(10) DEFAULT '')
CREATE TABLE #FeeRate (Expression VARCHAR(20) DEFAULT '', Price NUMERIC(10,2) DEFAULT 0, Description VARCHAR(50) DEFAULT '')

INSERT INTO #Detail VALUES ('001xxxxx')
INSERT INTO #Detail VALUES ('020xxxxx')
INSERT INTO #Detail VALUES ('021xxxxx')
INSERT INTO #Detail VALUES ('800xxxxx')
INSERT INTO #Detail VALUES ('400xxxxx')
INSERT INTO #Detail VALUES ('28011111')
INSERT INTO #Detail VALUES ('82188888')
INSERT INTO #Detail VALUES ('22223333')

INSERT INTO #FeeRate VALUES ('001%',  10.0, 'International call')
INSERT INTO #FeeRate VALUES ('0[^0]%', 5.0, 'National call')
INSERT INTO #FeeRate VALUES ('800%',   0.0, 'Free call')
INSERT INTO #FeeRate VALUES ('400%',   0.8,  '800 like, but caller need pay for local part')
INSERT INTO #FeeRate VALUES ('ELSE,How?',  0.2, 'Others/Local call')

SELECT * FROM #Detail
SELECT * FROM #FeeRate

SELECT
    *
FROM
    #Detail d
    LEFT JOIN #FeeRate f ON d.TelNO LIKE f.Expression

DROP TABLE #Detail
DROP TABLE #FeeRate

最佳答案

向您的 FeeRate 表中添加一个额外的列,称为 Priority。为应该“更早”发生的比赛分配更高的优先级。对费率表进行两次连接,第二次是左连接,并寻找更高优先级的匹配。如果左连接有效,则拒绝结果行:

CREATE TABLE #FeeRate (Expression VARCHAR(20) DEFAULT '', Price NUMERIC(10,2) DEFAULT 0, Description VARCHAR(50) DEFAULT '',Priority int)

INSERT INTO #FeeRate VALUES ('001%',  10.0, 'International call',5)
INSERT INTO #FeeRate VALUES ('0[^0]%', 5.0, 'National call',4)
INSERT INTO #FeeRate VALUES ('800%',   0.0, 'Free call',3)
INSERT INTO #FeeRate VALUES ('400%',   0.8,  '800 like, but caller need pay for local part',2)
INSERT INTO #FeeRate VALUES ('%',  0.2, 'Others/Local call',1)

SELECT * FROM #Detail d
    inner JOIN #FeeRate f ON d.TelNO LIKE f.Expression
    left join #FeeRate f_anti on d.TelNo LIKE f_anti.Expression and f_anti.Priority > f.Priority
where
    f_anti.Price is null

这可能还可以让您简化其他一些表达式。

关于sql - 从 SQL 数据实现 ELSE 表达式,可能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7566338/

相关文章:

sql-server - 使用从 sql 函数获取的值时 ORDER BY

Mysql SELECT 进程信息(完成百分比)

sql - 临时表列大小在多少行之后确定?

PHP MySQL 仅打印数据库行中的空列名称

C# Linq 使用Where 和IsNull() 运算符 '&&' 不能应用于类型 'bool' 和 'int?' 的操作数

c# - 无法连接到 Visual Studio 2012 Express For Web 中的本地数据库 : (error 26)(C#)(SQL Server 2012)

sql - sql游标的替代品

sql-server - SQL Server 和线程

sql - 填写空日期

sql - 给定机器的最后销售