开发者

Implement ELSE expression from SQL data, is it possible?

开发者 https://www.devze.com 2023-04-07 16:04 出处:网络
Suppose there\'re 2 tables with data like below: -- Table #Detail TelNO ---------- 001xxxxx 020xxxxx 021xxxxx

Suppose there're 2 tables with data like below:

-- 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

I want to select data from the 2 tables JOINed on dbo.FUNCTION_Match (TelNO, Expression) condition. (dbo.FUNCTION_Match is a crude function i wroted to match TelNO and Expression. In this sample, you can treat it as TelNO LIKE Expression).

So the SQL & query result is

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

The problem is clear, those local calls in #Detail can't matched Others FeeRate.

My crude FUNCTION_Match function has handled multi-expressions like TelNO NOT LIKE '0%' AND TelNO NOT LIKE [84]00% OR TelNO LIKE '0755%' to match Others FeeRate, but it's hard to write a correct multi-expression to express ELSE when there're many records in #FeeRate table.

So, is there a way to implement ELSE expression from data ?


SQLs to create sample data

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


Add an extra column to your FeeRate table, called Priority. Assign higher priorities to the matches that should occur "earlier". Do two joins to the fee rate table, the second being a left join, and looking for a higher priority match. If the left join works, reject the result row:

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

This probably allows you to simplify some of your other expressions also.


If there is only one "other" category, store its values in variables and substitute them in when there is no match using 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


I don't know for sure what data you are having in #Detail table, but for the above data you can do something like this:

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

精彩评论

暂无评论...
验证码 换一张
取 消