假设有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 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
答案 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