SQL帮助 - 加入其中并不需要所有列小查找表(和其它选项)

问题描述 投票:0回答:2

我有一个交易大表,并与我想基于4个相同的列添加值较小的查找表。这里的技巧是不是这4列的每个组合将在查找表中存在有某些场景下,我希望它停止检查,并接受了比赛,而不是去到下一列。我也有一个“其他”选项默认为,如果它不符合任何选项。

表结构是这样的:

transaction_table
country, trans_id, store_type, store_name, channel, browser, purchase_amount, currency

lookup_table
country, store_name, channel, browser, trans_fee

该数据可能是这样的:

transaction_table:

country| trans_id| store_type  |store_name  |channel |browser |amt  |currency
US     | 001     | Big Box     | Target     | B&M    |N/A     |1.45 |USD    
US     | 002     | Big Box     | Target     | Online |Chrome  |1.79 |USD   
US     | 003     | Small       | Bob's Store| B&M    |N/A     |2.50 |USD   
US     | 004     | Big Box     | Walmart    | B&M    |N/A     |1.12 |USD   
US     | 005     | Big Box     | Walmart    | Online |Firefox |3.79 |USD   
US     | 006     | Big Box     | Amazon     | Online |IE      |4.54 |USD   
US     | 007     | Small       | Jim's Plc  | B&M    |IE      |2.49 |USD 

lookup_table:
country|store_name  |channel |browser |trans_fee
US     |Target      |B&M     |N/A     |0.25   
US     |Target      |Online  |        |0.15
US     |Walmart     |        |        |0.30
US     |Other       |        |        |0.45

所以看lookup_table数据:

  • 第1行是非常具体的,将是连接列上的所有4匹配。
  • 第2行根本不会在乎使用什么浏览器在Target店所以无论“浏览器”值时,应trans_fee回来相同的(其他商店虽然可以不在乎)。
  • 第3行是与一个国家=“美国”和STORE_NAME =“沃尔玛”说的任何交易,无论是连接列的其余部分将具有相同的trans_fee
  • 第4行是“其他”的情况下,它应该首先要看STORE_NAME列,如果没有找到匹配,去其他。

该lookup_table数据可以改变,可能最终会被(添加起始日期日期和结束日期列)随时间变化的,因此真的不会成为一个长期的,复杂的CASE语句一个很好的候选人。

我想检查与一个IF语句中每一列的组合,但我希望有一个我可以使用栏上栏,并有其他选择一个更简单的条件加入类型的语句。

谢谢!

编辑:我没有具体说明这一点,但我想基本上是从transaction_table返回所有的数据和相应的trans_fee添加到每一行。

sql join
2个回答
0
投票

您将需要使用条件JOIN。

像这样的事情

SELECT * 
FROM lookup_table
LEFT OUTER JOIN transaction_table
ON CASE WHEN lookup_table.store_name IS NOT NULL 
THEN transacton_table.store_name = lookup_table.store_name END

0
投票

这种部分匹配是棘手的。而你的问题是不是真的那么好设置。你似乎有在其他一些列和一般价值NULLs。

在任何情况下,你可以通过匹配一下就可以了,然后用order by,以获得最佳匹配解决这个问题。在你的情况,我认为这是这样的:

select tt.*,
       (select trans_fee
        from lookup l
        where l.country = tt.country and
              l.store_name in ('other', tt.store_name) and
              (l.channel = tt.channel or l.channel is null) and
              (l.browser = tt.browser or l. browser is null)
        order by (case when l.store_name = tt.store_name then 1 else 2 end),
                 (case when l.channel = tt.channel then 1 else 2 end),
                 (case when l.browser = tt.browser then 1 else 2 end)
        fetch first 1 row only
       ) as trans_fee
from transaction_table tt;

这是通用的SQL。但同样的想法应该在任何数据库。

© www.soinside.com 2019 - 2024. All rights reserved.