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

时间:2011-09-27 08:42:17

标签: 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 Expression )。< / p>

所以SQL&amp;查询结果是

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,但是当记录很多时,很难编写正确的多表达式来表达ELSE在#FeeRate表中。

那么,有没有办法从数据中实现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

3 个答案:

答案 0 :(得分:2)

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

这可能允许您简化其他一些表达式。

答案 1 :(得分:2)

如果只有一个“其他”类别,请将其值存储在变量中,并在使用ISNULL无匹配时替换它们:

DECLARE @expression VARCHAR(20), @price NUMERIC (10,2), @description VARCHAR(50)

SELECT @expression = Expression, @price = Price, @description = [Description]
FROM #FeeRate 
WHERE Expression = 'ELSE,How?'

SELECT d.TelNO, ISNULL(f.Expression, @expression) AS Expression,
ISNULL(f.Price, @price) AS Price,
ISNULL(f.[Description], @description) AS [Description]  
FROM
    #Detail d
    LEFT JOIN #FeeRate f ON d.TelNO LIKE f.Expression

答案 2 :(得分:1)

我不确定您在#Detail表中有哪些数据,但对于上述数据,您可以执行以下操作:

SELECT * FROM
            #Detail d
                LEFT JOIN #FeeRate f ON 
                    (CASE 
                        WHEN d.TelNO LIKE '%xxxxx' THEN TelNO 
                        ELSE 'ELSE,How?' 
                     END) LIKE f.Expression