【问题标题】:How can we do a simple join like this in Oracle?我们如何在 Oracle 中进行这样的简单连接?
【发布时间】:2018-12-11 02:44:38
【问题描述】:

我们如何进行这样的简单连接?

我有三张桌子:

表 1:学生

UserID
11111111111
22222222222
33333333333
44444444444
55555555555
66666666666
77777777777
88888888888
99999999999

表 2:

ClassID | StartDate
0001    | Apr 2,2018, 9:00 AM
0002    | May 2,2018, 9:00 AM

表 3:注册

UserID      | ClassID
11111111111 | 0001
11111111111 | 0002
22222222222 | 0001
33333333333 | 0002

我需要下表:

预期表格

UserID      | ClassID | StartDate
11111111111 | 0001    | Apr 2,2018, 9:00 AM
11111111111 | 0002    | May 2,2018, 9:00 AM
22222222222 | 0001    | Apr 2,2018, 9:00 AM
33333333333 | 0002    | May 2,2018, 9:00 AM
44444444444 | null    | null
55555555555 | null    | null
66666666666 | null    | null
77777777777 | null    | null
88888888888 | null    | null
99999999999 | null    | null

如果可能,请不要使用UNION

进一步编辑

表 3:注册(带有新的“EnrollStatus”列)

UserID      | ClassID | EnrollStatus
11111111111 | 0001    | Enrolled
11111111111 | 0002    | Enrolled
22222222222 | 0001    | Enrolled
33333333333 | 0002    | Enrolled

预期的表格(带有新的“EnrollStatus”列)

UserID      | ClassID | StartDate           | EnrollStatus
11111111111 | 0001    | Apr 2,2018, 9:00 AM | Enrolled
11111111111 | 0002    | May 2,2018, 9:00 AM | Enrolled
22222222222 | 0001    | Apr 2,2018, 9:00 AM | Enrolled
22222222222 | null    | null                | null
33333333333 | null    | null                | null
33333333333 | 0002    | May 2,2018, 9:00 AM | Enrolled
44444444444 | null    | null                | null
44444444444 | null    | null                | null
55555555555 | null    | null                | null
55555555555 | null    | null                | null
66666666666 | null    | null                | null
66666666666 | null    | null                | null
77777777777 | null    | null                | null
77777777777 | null    | null                | null
88888888888 | null    | null                | null
88888888888 | null    | null                | null
99999999999 | null    | null                | null
99999999999 | null    | null                | null

我认为这个 JOIN 是必要的,因为我有另一个表(进一步),其中包含一年中的日期,我需要计算用户没有在特定时期(过滤器)注册的周数。此外,需要显示用户未注册的周数(按用户)。

表 4:日期(来自:SQL working week in Oracle

WITH DATES AS
(
  SELECT DATE '2017-12-25' + LEVEL -1 dt FROM DUAL CONNECT BY LEVEL <= 500
)
SELECT dt,TO_CHAR(dt,'DY') DAY,TO_CHAR(dt,'WW') WW,TO_CHAR(dt,'IW') IW,
   CASE WHEN TO_CHAR(dt,'D')<TO_CHAR(TO_DATE(TO_CHAR(dt,'YYYY')||'0101','YYYYMMDD'),'D') THEN 
     LPAD(TO_CHAR(dt,'WW')+1,2,'0')
   ELSE 
     TO_CHAR(dt,'WW')
   END MY
FROM dates

查询结果

DT                    | DAY | WW | IW | MY
Dec 25, 2017, 3:00 AM | MON | 52 | 52 | 52
Dec 26, 2017, 3:00 AM | TUE | 52 | 52 | 52
Dec 27, 2017, 3:00 AM | WED | 52 | 52 | 52
Dec 28, 2017, 3:00 AM | THU | 52 | 52 | 52
Dec 29, 2017, 3:00 AM | FRI | 52 | 52 | 52
Jan 1, 2018, 3:00 AM  | MON | 01 | 01 | 01
Jan 2, 2018, 3:00 AM  | TUE | 01 | 01 | 01
Jan 3, 2018, 3:00 AM  | WED | 01 | 01 | 01
Jan 4, 2018, 3:00 AM  | THU | 01 | 01 | 01
Jan 5, 2018, 3:00 AM  | FRI | 01 | 01 | 01
Jan 8, 2018, 3:00 AM  | MON | 02 | 02 | 02
Jan 9, 2018, 3:00 AM  | TUE | 02 | 02 | 02
Jan 10, 2018, 3:00 AM | WED | 02 | 02 | 02
Jan 11, 2018, 3:00 AM | THU | 02 | 02 | 02
Jan 12, 2018, 3:00 AM | FRI | 02 | 02 | 02
Jan 15, 2018, 3:00 AM | MON | 03 | 03 | 03
Jan 16, 2018, 3:00 AM | TUE | 03 | 03 | 03
Jan 17, 2018, 3:00 AM | WED | 03 | 03 | 03
Jan 18, 2018, 3:00 AM | THU | 03 | 03 | 03
Jan 19, 2018, 3:00 AM | FRI | 03 | 03 | 03

【问题讨论】:

  • 到目前为止你做了什么?
  • 您正在寻找外连接
  • @Dragonthoughts,我试过LEFT JOIN,但我在原来的问题中遗漏了一些细节......所以我进行了更正和补充。
  • @a_horse_with_no_name,我也试过这个。您能考虑一下我更正后的问题吗?

标签: sql oracle join oracle11g


【解决方案1】:

您可以尝试在Student 表的基础上使用LEFT JOIN

SELECT s.*,e.*,c.* 
  FROM Student s 
  LEFT JOIN Enroll e on s.UserID =e.UserID
  LEFT JOIN Class c on c.ClassID =e.ClassID 
 ORDER BY s.UserID

Sqlfiddle

编辑

我看到你编辑了你的问题,你似乎想要得到笛卡尔积。

您需要在学生表和班级上CROSS JOIN,然后LEFT JOIN

SELECT s.userID,
       e.CLASSID,
       (CASE WHEN e.CLASSID IS NULL then NULL else c.STARTDATE END) STARTDATE,
       e.EnrollStatus
FROM 
Student s 
CROSS JOIN Class c 
LEFT JOIN Enroll e
    on s.UserID =e.UserID AND e.CLASSID = c.CLASSID
ORDER BY s.UserID

结果

|      USERID | CLASSID |           STARTDATE | ENROLLSTATUS |
|-------------|---------|---------------------|--------------|
| 11111111111 |    0001 | Apr 2,2018, 9:00 AM | EnrollStatus |
| 11111111111 |    0002 | May 2,2018, 9:00 AM | EnrollStatus |
| 22222222222 |    0001 | Apr 2,2018, 9:00 AM | EnrollStatus |
| 22222222222 |  (null) |              (null) |       (null) |
| 33333333333 |  (null) |              (null) |       (null) |
| 33333333333 |    0002 | May 2,2018, 9:00 AM | EnrollStatus |
| 44444444444 |  (null) |              (null) |       (null) |
| 44444444444 |  (null) |              (null) |       (null) |
| 55555555555 |  (null) |              (null) |       (null) |
| 55555555555 |  (null) |              (null) |       (null) |
| 66666666666 |  (null) |              (null) |       (null) |
| 66666666666 |  (null) |              (null) |       (null) |
| 77777777777 |  (null) |              (null) |       (null) |
| 77777777777 |  (null) |              (null) |       (null) |
| 88888888888 |  (null) |              (null) |       (null) |
| 88888888888 |  (null) |              (null) |       (null) |
| 99999999999 |  (null) |              (null) |       (null) |
| 99999999999 |  (null) |              (null) |       (null) |

CORSS JOIN

【讨论】:

  • 谢谢!但这不起作用,因为我最初的问题是一些错误。你能考虑一下我更正的问题吗?
  • 您能否从您的预期结果中给我更多详细信息?以及表 4 上的关系是什么:日期
  • D-Shih,作为我的最终结果,我需要一个表格来显示所有用户和所有类,其中包含以下列:UserID | ClassID | StartDate | EnrollStatus | WW | COUNT *WW 表示一年中的周数所以如果我有 1000 个用户和 500 个类,这个表应该是 500000 行。 ...
  • ... 想象一个控制所有员工培训时间的报告,该报告的一部分显示用户未注册(注册)的周数。此外,另一列显示那些周是什么(考虑在新的JOIN 中使用LISTAGG,使用日期来链接表格:Table 4 Dates x Expected Table)。
  • ...COUNT 用于计算未注册(注册)的周数。
猜你喜欢
  • 1970-01-01
  • 2013-05-04
  • 2019-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多