假设有 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
是我编写的一个粗略函数,用于匹配 TelNO
和 Expression
。在此示例中,您可以将其视为 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/