【问题标题】:Oracle SQL Joining on Null Value空值上的 Oracle SQL 联接
【发布时间】:2017-10-19 11:27:47
【问题描述】:

我有点 sql nublet 所以希望你能忍受我。

我有 2 个表,我正在执行左外连接(日历和员工)。

第一个表是 2005 年到 2030 年之间的日期列表,第二个表是员工打卡时间列表。

我需要使用这两个表创建一个输出,以显示员工在指定的一周内何时打卡或没有打卡。

这是我在下面使用的代码:

select cal.account_date,
cal.day_value,
Emp_Clock.emp_no,
Emp_Clock.Basic,
Emp_Clock.MWOT,
Emp_Clock.WEOT,
Emp_Clock.Clean
from

(Select work_day as account_date, 
Work_Time_Calendar_API.Get_Week_Day(WORK_DAY) as Day_Value from Calendar
where
Calendar_ID = '24/7'
and
work_day between 
          to_date(CALENDAR_API.Get_First_Week_Day ('2017', '&WEEK_NO', '6' )) 
      AND to_date(CALENDAR_API.Get_First_Week_Day ('2017', '&WEEK_NO', '6' ))+6) Cal

Left Outer Join

(select company_id,emp_no , account_date,
round(max(decode(wage_code,'MWOT',wage_hours)),2) as MWOT, 
round(max(decode(wage_code,'BASIC',wage_hours)),2) as BASIC,
round(max(decode(wage_code,'WEOT',wage_hours)),2) as WEOT,
round(max(decode(wage_code,'CLEAN',wage_hours)),2) as CLEAN,
ifsapp.Work_Time_Calendar_API.Get_Week_Day(account_date) as Day_Value
from Employees where company_ID = 'Redacted'  
group by emp_no, account_date,company_ID
order by emp_no) Emp_Clock

on cal.account_date = emp_clock.account_date

order by emp_clock.emp_no, cal.account_date

目前该表仅提取员工工作的日期(current_result.jpg),我认为这是因为我正在加入日期(我可以加入的唯一字段)。

是否有任何可能的方法可以让我重新处理此查询以拉回我所追求的结果 (Desired_Result.jpg),或者两个表中没有足够的信息来以这种方式进行连接。

当前结果:

预期结果:

编辑:子查询结果的附件

Subquery Result

编辑 2:

子查询 1 的结果:

Account_Date               Day_Value
7/1/2017   00:00:00         Saturday
8/1/2017   00:00:00         Sunday
9/1/2017   00:00:00         Monday
10/1/2017  00:00:00         Tuesday
11/1/2017  00:00:00         Wednesday

子查询 2 的结果:

Company_ID  Emp_No  account_date  MWOT  BASIC    WEOT    CLEAN  Day_VALUE
 Redacted     1       9/1/2017    null    8      null     null   Monday
 Redacted     1      10/1/2017    null    8      null     null   Tuesday
 Redacted     1      11/1/2017    null    8      null     null   Wednesday
 Redacted     2       7/1/2017    null   null      8      null   Saturday
 Redacted     2       9/1/2017    null    8      null     null   Monday
 Redacted     2      10/1/2017    null    8      null     null   Tuesday
 Redacted     3       9/1/2017     2     9.25    null     null   Monday
 Redacted     3      10/1/2017     2     9.25    null     null   Tuesday
 Redacted     3      11/1/2017     2     9.25    null     null  Wednesday

【问题讨论】:

  • 如果单独运行:表“日历”上的第一个子查询是否产生所有必需的日期? (左连接应该允许列出所有日期。
  • 是的,我已将子查询的输出添加到主体中。
  • 抱歉,刚刚注意到您在第二个子查询中有一个 order by。摆脱它,然后再试一次。除此之外,我看不到任何会阻止预期结果的东西。
  • 我已经按照建议在第二个子查询中删除了 order by,但它仍然拉回了相同的结果。感谢您的帮助。
  • 从第一个子查询和第二个子查询(分别)提供一些示例数据(作为文本,而不是图像LEFT JOIN 允许空值你可以从示例数据中省略名称等。这只是我们想要的样本,而不是重载

标签: sql join oracle11g


【解决方案1】:

您现有的查询缺少所有员工编号的列表(您需要该查询),并且该列表应“交叉连接”到日期以生成 date/emp_no 的所有组合。一旦该笛卡尔积存在,然后将连接日期保留为日期,并将 emp_no 保留为 emp_no,以输出所有行,即使单击的小时数之间存在间隔。

查看此工作演示:SQL Fiddle

Oracle 11g R2 架构设置

CREATE TABLE SUBQRY1
    (ACCOUNT_DATE TIMESTAMP, DAY_VALUE VARCHAR2(9))
;

INSERT ALL 
    INTO SUBQRY1 (Account_Date, Day_Value)
         VALUES ('01-Jul-2017 12:00:00 AM', 'Saturday')
    INTO SUBQRY1 (Account_Date, Day_Value)
         VALUES ('01-Aug-2017 12:00:00 AM', 'Sunday')
    INTO SUBQRY1 (Account_Date, Day_Value)
         VALUES ('01-Sep-2017 12:00:00 AM', 'Monday')
    INTO SUBQRY1 (Account_Date, Day_Value)
         VALUES ('01-Oct-2017 12:00:00 AM', 'Tuesday')
    INTO SUBQRY1 (Account_Date, Day_Value)
         VALUES ('01-Nov-2017 12:00:00 AM', 'Wednesday')
SELECT * FROM dual
;

CREATE TABLE SUBQRY2
    (COMPANY_ID VARCHAR2(8), EMP_NO INT, ACCOUNT_DATE TIMESTAMP, MWOT VARCHAR2(4), BASIC VARCHAR2(4), WEOT VARCHAR2(4), CLEAN VARCHAR2(4), DAY_VALUE VARCHAR2(9))
;

INSERT ALL 
    INTO SUBQRY2 (Company_ID, Emp_No, account_date, MWOT, BASIC, WEOT, CLEAN, Day_VALUE)
         VALUES ('Redacted', 1, '01-Sep-2017 12:00:00 AM', NULL, '8', NULL, NULL, 'Monday')
    INTO SUBQRY2 (Company_ID, Emp_No, account_date, MWOT, BASIC, WEOT, CLEAN, Day_VALUE)
         VALUES ('Redacted', 1, '01-Oct-2017 12:00:00 AM', NULL, '8', NULL, NULL, 'Tuesday')
    INTO SUBQRY2 (Company_ID, Emp_No, account_date, MWOT, BASIC, WEOT, CLEAN, Day_VALUE)
         VALUES ('Redacted', 1, '01-Nov-2017 12:00:00 AM', NULL, '8', NULL, NULL, 'Wednesday')
    INTO SUBQRY2 (Company_ID, Emp_No, account_date, MWOT, BASIC, WEOT, CLEAN, Day_VALUE)
         VALUES ('Redacted', 2, '01-Jul-2017 12:00:00 AM', NULL, NULL, '8', NULL, 'Saturday')
    INTO SUBQRY2 (Company_ID, Emp_No, account_date, MWOT, BASIC, WEOT, CLEAN, Day_VALUE)
         VALUES ('Redacted', 2, '01-Sep-2017 12:00:00 AM', NULL, '8', NULL, NULL, 'Monday')
    INTO SUBQRY2 (Company_ID, Emp_No, account_date, MWOT, BASIC, WEOT, CLEAN, Day_VALUE)
         VALUES ('Redacted', 2, '01-Oct-2017 12:00:00 AM', NULL, '8', NULL, NULL, 'Tuesday')
    INTO SUBQRY2 (Company_ID, Emp_No, account_date, MWOT, BASIC, WEOT, CLEAN, Day_VALUE)
         VALUES ('Redacted', 3, '01-Sep-2017 12:00:00 AM', '2', '9.25', NULL, NULL, 'Monday')
    INTO SUBQRY2 (Company_ID, Emp_No, account_date, MWOT, BASIC, WEOT, CLEAN, Day_VALUE)
         VALUES ('Redacted', 3, '01-Oct-2017 12:00:00 AM', '2', '9.25', NULL, NULL, 'Tuesday')
    INTO SUBQRY2 (Company_ID, Emp_No, account_date, MWOT, BASIC, WEOT, CLEAN, Day_VALUE)
         VALUES ('Redacted', 3, '01-Nov-2017 12:00:00 AM', '2', '9.25', NULL, NULL, 'Wednesday')
SELECT * FROM dual
;

查询 1

with subqry3 as (
  /* this is just an example, you don't have to do it this way */
  select distinct Emp_No from subqry2
  )

select
*
from subqry1 d /* d = dates */
cross join subqry3 e /* e = employess */
left join subqry2 h  /* h = hours */
    on d.Account_Date = h.Account_Date
   and e.emp_no = h.emp_no
order by e.emp_no, d.Account_Date
;

Results

|          ACCOUNT_DATE | DAY_VALUE | EMP_NO | COMPANY_ID | EMP_NO |          ACCOUNT_DATE |   MWOT |  BASIC |   WEOT |  CLEAN | DAY_VALUE |
|-----------------------|-----------|--------|------------|--------|-----------------------|--------|--------|--------|--------|-----------|
| 2017-07-01 00:00:00.0 |  Saturday |      1 |     (null) | (null) |                (null) | (null) | (null) | (null) | (null) |    (null) |
| 2017-08-01 00:00:00.0 |    Sunday |      1 |     (null) | (null) |                (null) | (null) | (null) | (null) | (null) |    (null) |
| 2017-09-01 00:00:00.0 |    Monday |      1 |   Redacted |      1 | 2017-09-01 00:00:00.0 | (null) |      8 | (null) | (null) |    Monday |
| 2017-10-01 00:00:00.0 |   Tuesday |      1 |   Redacted |      1 | 2017-10-01 00:00:00.0 | (null) |      8 | (null) | (null) |   Tuesday |
| 2017-11-01 00:00:00.0 | Wednesday |      1 |   Redacted |      1 | 2017-11-01 00:00:00.0 | (null) |      8 | (null) | (null) | Wednesday |
| 2017-07-01 00:00:00.0 |  Saturday |      2 |   Redacted |      2 | 2017-07-01 00:00:00.0 | (null) | (null) |      8 | (null) |  Saturday |
| 2017-08-01 00:00:00.0 |    Sunday |      2 |     (null) | (null) |                (null) | (null) | (null) | (null) | (null) |    (null) |
| 2017-09-01 00:00:00.0 |    Monday |      2 |   Redacted |      2 | 2017-09-01 00:00:00.0 | (null) |      8 | (null) | (null) |    Monday |
| 2017-10-01 00:00:00.0 |   Tuesday |      2 |   Redacted |      2 | 2017-10-01 00:00:00.0 | (null) |      8 | (null) | (null) |   Tuesday |
| 2017-11-01 00:00:00.0 | Wednesday |      2 |     (null) | (null) |                (null) | (null) | (null) | (null) | (null) |    (null) |
| 2017-07-01 00:00:00.0 |  Saturday |      3 |     (null) | (null) |                (null) | (null) | (null) | (null) | (null) |    (null) |
| 2017-08-01 00:00:00.0 |    Sunday |      3 |     (null) | (null) |                (null) | (null) | (null) | (null) | (null) |    (null) |
| 2017-09-01 00:00:00.0 |    Monday |      3 |   Redacted |      3 | 2017-09-01 00:00:00.0 |      2 |   9.25 | (null) | (null) |    Monday |
| 2017-10-01 00:00:00.0 |   Tuesday |      3 |   Redacted |      3 | 2017-10-01 00:00:00.0 |      2 |   9.25 | (null) | (null) |   Tuesday |
| 2017-11-01 00:00:00.0 | Wednesday |      3 |   Redacted |      3 | 2017-11-01 00:00:00.0 |      2 |   9.25 | (null) | (null) | Wednesday |

【讨论】:

  • 感谢所有帮助。这确实解决了问题:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 2020-03-13
  • 2012-03-03
  • 1970-01-01
  • 2014-06-09
  • 1970-01-01
相关资源
最近更新 更多