【问题标题】:Oracle "Starts With" text join, excluding nullsOracle“开始于”文本连接,不包括空值
【发布时间】:2013-04-12 04:53:20
【问题描述】:

我遇到了一些麻烦。我正在尝试构建一个使用“开始于”逻辑的 SQL 查询。先说一点背景...

在我负责编写报告的数据库中,有一个“用户”表和一个“销售人员”表,销售人员属于一个用户。在一个不太聪明的举动中,数据库的设计者决定通过子字符串匹配销售人员与他们的员工代码相关联。例如:

John Smith 的“employee_code”将是“JS”。但他有多个“销售人员”来区分他不同的销售类型。所以他可能有“JS1”、“JS2”、“JS3”等,作为他的“salesperson_code”。

举例说明:

user table:
|----------|-----------|----------|---------------|
| username | firstname | lastname | employee_code |
|----------|-----------|----------|---------------|
| JSMITH   | John      | Smith    | JS            |
|----------|-----------|----------|---------------|

salesperson table:
|------------------|------------------|
| salesperson_name | salesperson_code |
|------------------|------------------|
| John Smith 1     | JS1              |
| John Smith 2     | JS2              |
| John Smith 3     | JS3              |
|------------------|------------------|

salesperson 表上没有将它们链接到用户表的外键,只有员工代码的子字符串。

我不记得我在哪里找到了这个答案,但在我的查询中我一直在这样做:

select user.name 
from user user
inner join salesperson spn on spn.salesperson_code like user.employee_code || '%'

这个逻辑成功地完成了“开始于”匹配。但是,有些用户的员工代码为空白,他们也匹配此查询。

我在寻找什么:如何修改此查询,以便如果employee_code 为空,它将不匹配?我是Oracle 查询的新手。其他 DBMS 有一个与空白字段不匹配的开头子句。

提前感谢您的帮助!

【问题讨论】:

  • ...AND user.employee_code IS NOT NULL?
  • 更改数据库。
  • 如果这是一个选项,比尔,我不会写这个问题。 ://

标签: oracle sql-like startswith


【解决方案1】:

试试这个

select user.name 
from user user
inner join salesperson spn 
on spn.salesperson_code like nvl(trim(user.employee_code),'-') || '%'

【讨论】:

  • 我建议使用@AlvaroGVicario 的回复。在这种情况下,NVL 将工作,但我总是担心在这种比较中引入函数调用 - 另外,使用 NVL 会混淆意图(即强制 NULL 不匹配任何内容 - 并且如果 EMPLOYEE_CODE 值恰好以“-”开头,这甚至可能不会成功)。更好的 IMO 使用LIKE USER.EMPLOYEE_CODE || '%' AND USER.EMPLOYEE_CODE NOT NULL。 YMMV。分享和享受。
【解决方案2】:

试试

select user.name 
from user user
inner join salesperson spn
  on spn.salesperson_code like DECODE (user.employee_code,
                                         NULL, NULL, 
                                               user.employee_code || '%')

【讨论】:

  • 嗯。查看解码函数,我不想测试空值,我想测试空字符串。也许应该是这个? select user.name from user user inner join salesperson spn on spn.salesperson_code like DECODE (user.employee_code, '', NULL, user.employee_code || '%')
  • Oracle 中没有“空字符串”之类的东西。
  • 哇,很高兴知道这一点。那我为什么不放一个 and employee_code is not null 呢?
  • 我应该澄清我的陈述。如果您尝试将 '' 插入到列中,Oracle 将有助于接受输入,但将存储 NULL
  • @user963076 与往常一样,解决给定问题的方法通常不止一种……建议的查询只是一种可能的解决方案……
【解决方案3】:

我建议使用正则表达式来提取销售人员代码的非数字部分以及可选的数字部分。使用这些添加的字段为表创建一个视图,或将其用作查询中的表表达式。

SELECT regexp_substr(salesperson_code,'\D+') AS employee_code,
       regexp_substr(salesperson_code,'\d+') AS employee_sales_no,
       salesperson_name, salesperson_code
FROM salesperson 

注意:正则表达式分别匹配一个或多个非数字和一个或多个数字。

【讨论】:

    【解决方案4】:

    添加IS NOT NULL 条件:

    select *
    from user
    inner join salesperson spn
            on spn.salesperson_code like user.employee_code || '%'
           and user.employee_code is not null;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-25
      • 2017-11-30
      • 1970-01-01
      • 2016-01-20
      • 1970-01-01
      • 2010-09-26
      • 1970-01-01
      相关资源
      最近更新 更多