【问题标题】:Complex Select Query In OracleOracle中的复杂选择查询
【发布时间】:2018-02-19 14:50:48
【问题描述】:

我有以下 3 张桌子 1- 雇员为:

EmpID EmpName -------------- 100 亚当 101史密斯

2- 转换为:

ShiftID ShiftName FromTime ToTinme -------------------------------------- 1 班次 1 上午 9 点 下午 2 点 2 班次 2 下午 3 点 5 点

3-EmpShifts 为:

EMPID SHIFTID 日期 --------------------------------- 100 1,2 2017 年 1 月 12 日 100 2 2017 年 2 月 12 日 101 1 2017 年 1 月 12 日 101 1,2 2017 年 2 月 12 日

我需要做一个 select 语句来获取数据 像这样:

EMPID EmpName Date ShiftID ShiftName ShiftTimes -------------------------------------------------- ---------------------- 100 亚当 2017 年 1 月 12 日 1 班次1 100 亚当 2017 年 1 月 12 日 2 班次2 100 亚当 2017 年 2 月 12 日 2 班次2 101 史密斯 2017 年 1 月 12 日 2 班次2 101 史密斯 02/12/2017 1 班次1 101 史密斯 2017 年 2 月 12 日 2 班次2

那么如何得到它。

【问题讨论】:

  • 你试过了吗?不要在表格中存储 CSV。
  • 你真的称之为“复杂”吗?
  • EmpShifts.SHIFTID 列有逗号分隔值吗?这不好
  • 我知道,但很抱歉我无法更改当前架构
  • EmpShifts 表中的SHIFTID 列不遵循1NF 规则,因为该字段中没有存储原子值。您必须先规范化该表,然后您才能使用简单的连接子句来获得所需的结果。

标签: sql oracle


【解决方案1】:

正如 cmets 中所述,这是一种糟糕的数据格式。将列表存储为字符串是不好的。以下是一些原因:

  • 数字应存储为数字,而不是字符串。
  • 具有相同名称 (shiftid) 的列应该包含相同的内容。
  • 应正确声明外键引用。
  • 字符串操作的效率远低于其他方法。

也就是说,你可以做你想做的事,使用类似like 的东西进行比较。以下查询显示了您需要的构造:

select . . .
from empshifts es join
     shifts s
     on ',' || shiftid || ',' like '%,' || s.shiftid || ',%' join
     employees e
     on e.empid = es.empid;

【讨论】:

    【解决方案2】:

    我没有运行查询,但它会工作

    试试这个

    with shifids as (
    select empid,date,regexp_substr(SHIFTID,'[^,]+', 1, level)shifid from EmpShifts 
       connect by regexp_substr(SHIFTID, '[^,]+', 1, level) is not null
       )
    select EmpLoyees.empid,EmpLoyees.empname,
    shifids.date,shifids.shifid,
    Shifts.ShiftID,Shifts.ShiftName
    from
    EmpLoyees inner join
    shifids
    on EmpLoyees.empid=shifids.empid
    inner join Shifts on Shifts .shiftid=shifids.shifid
    

    【讨论】:

      【解决方案3】:

      正如所有人所说,用逗号分隔存储列表是个坏主意。

      但这里也有一个解决方案 INSTR 存在:

      SELECT 
          E."EmpID",
          E."EmpName",
          ES."Date",
          S."ShiftID",
          S."ShiftName"
      FROM EmpShifts ES
      INNER JOIN Shifts S ON INSTR(ES."SHIFTID", S."ShiftID", 1, 1) > 0
      INNER JOIN EmpLoyees E ON ES."EMPID" = E."EmpID"
      

      不确定它是否是您想要的,但请尝试一下,这是 SQLFiddle 中的 demo

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-03-16
        • 2013-08-29
        • 1970-01-01
        • 2016-10-07
        • 2015-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多