【问题标题】:Oracle Query on Comma Separated Values In a ColumnOracle 查询列中逗号分隔的值
【发布时间】:2015-03-25 09:26:54
【问题描述】:

我有两张桌子。一张表是接入点列表。另一个是谁可以访问什么的列表。 它曾经是一个人可以访问一件事或所有事物。但是,现在情况发生了变化。现在有人可能可以访问几个点。 系统中的扳手是在显示他们有权访问的列中可能有一个值,“ALL”表示所有访问或逗号分隔的列表(这是新的)。 我原本以为我可以只做WHERE Access_To Here IN(),但我不确定如何将 Access_To 的值转换为格式化列表。 我需要能够将其作为单个查询来执行,因为我将它用于 APEX 中的 LOV。 所以,我需要一些帮助。

Access_Points_Table 只有一列,Access_Points。以下是它可能具有的一些示例值:

CSX
CZR
XR3
NBO
QHG

Users_List 表有几列,但最重要的是 User_Name、Access_To。以下是它可能具有的一些示例值:

Joe | ALL
Fred | CSX
Allen | CZR, NBO
Hank | QHG

这是我目前正在使用的查询,但它仅在 Access_To 列中只有一个值时才有效。

SELECT DISTINCT Access_Points VALUE
FROM Access_Points_Table apt
JOIN
Users_List ul
ON (ul.wwid = 'ZZ999'
AND (ul.Access_To = 'ALL' OR apt.symbol_name = ul.Access_To))
ORDER BY name ASC  

我想要完成的是:

SELECT DISTINCT Access_Points VALUE
FROM Access_Points_Table apt
JOIN
Users_List ul
ON (ul.wwid = 'ZZ999'
AND (ul.Access_To = 'ALL' OR apt.symbol_name IN(Something Goes Here)))
ORDER BY name ASC       

因此,如果对用户 Allen 运行查询,它将返回行:

CZR
NBO

【问题讨论】:

  • 存储逗号分隔值是糟糕设计的标志。此外,in 不会对它们起作用。
  • 该死的。粘贴了错误的链接。我的意思是:“Oracle 10g Splitting string into multiple rows 的重复”。
  • 也许这是一个糟糕的设计,但不幸的是,我不是 DBA,只是开发人员。
  • 很抱歉听到这个消息。这是开发人员可能犯的错误,但了解规范化的专用 DBA 不应该这样做。无论如何,我认为您可以在我提供的链接中找到答案。

标签: sql oracle oracle-apex


【解决方案1】:

另一种方法是使用 instr 测试:

SELECT DISTINCT access_points VALUE FROM access_points_table 一个 加入 users_list u 开启 ( INSTR(u.access_to,a.access_points,1) > 0 ) 按 1 订购

【讨论】:

    【解决方案2】:

    根据你的逗号分隔数据的长度,可以使用Oracle的正则表达式引擎(难点是Oracle将正则表达式限制为512字节):

    SELECT DISTINCT Access_Points VALUE
      FROM Access_Points_Table apt
      JOIN Users_List ul
        ON ( ul.wwid = 'ZZ999'
       AND ( ul.Access_To = 'ALL'
          OR REGEXP_LIKE(apt.symbol_name, '^(' || REPLACE(ul.Access_To, ',', '|') || ')$') ) )
     ORDER BY name ASC
    

    您也可以使用LIKE:

    SELECT DISTINCT Access_Points VALUE
      FROM Access_Points_Table apt
      JOIN Users_List ul
        ON ( ul.wwid = 'ZZ999'
       AND ( ul.Access_To = 'ALL'
          OR ',' || ul.Access_To || ',' LIKE '%,' || apt.symbol_name || ',%' ) )
     ORDER BY name ASC
    

    请注意,如果Access_To 的逗号后面有空格,就像在您的 OP 中一样,它确实会增加一些复杂性,但可以克服,只需 REPLACE(ul.Access_To, ' ')。

    顺便说一句,我确实想知道为什么:ul.wwid = 'ZZ999' 在 ON 子句中,而不是在 WHERE 子句中。

    【讨论】:

      猜你喜欢
      • 2020-09-14
      • 2014-07-02
      • 1970-01-01
      • 1970-01-01
      • 2013-10-26
      • 1970-01-01
      • 1970-01-01
      • 2019-05-23
      • 2011-06-18
      相关资源
      最近更新 更多