设为首页 收藏本站
查看: 523|回复: 0

[经验分享] Mastering Oracle SQL学习:连接 (转载)

[复制链接]

尚未签到

发表于 2016-7-22 11:03:04 | 显示全部楼层 |阅读模式
1.JOIN的基本概念:
A join is a SQL query that extracts information from two or more tables or views. When you specify multiple tables or views in the FROM clause of a query, Oracle performs a join, linking rows from multiple tables together. There are several types of joins to be aware of:
    A.Inner joins
  Inner joins are the regular joins. An inner join returns the rows that satisfy the join     condition. Each row returned by an inner join contains data from all tables involved  in the join.
 
    B.Outer joins
    Outer joins are an extension to the inner joins. An outer join returns the rows that    satisfy the join condition and also the rows from one table for which no corresponding  rows exist in the other table.
 
    C.Self joins
    A self join is a join of a table to itself.
 
2.笛卡儿积:
If you don't specify the join condition while joining two tables, Oracle combines each row from the first table with each row of the second table. This type of result set is called as a Cartesian product. The number of rows in a Cartesian product is the product of the number of rows in each table.
 
3.JOIN的条件:
Usually the join condition is specified on the foreign key columns of one table and the primary key or unique key columns of another table. However, you can specify other columns as well. Each join condition involves columns that relate two tables.
 
A join condition may involve more than one column. This is usually the case when a foreign key constraint consists of multiple columns.
 
A join condition must involve columns with compatible datatypes. Note that the datatype of the columns involved in a join condition need to be compatible, not the same. Oracle performs automatic datatype conversion between the join columns, if required
 
4.外连接的语法:
The syntax of the outer join is a bit different from that of the inner join, because it includes a special operator called the outer join operator. The outer join operator is a plus sign enclosed in parentheses, i.e., (+). This operator is used in the join condition in the WHERE clause following a field name from the table that you wish to be considered the optional table.(如果表A中某条记录在表B中没有对应的记录存在,而又想列出表A中所有的记录,此时采用内连接将无法达到目的。可以采用外连接的方法,在WHERE子句中,表B相应字段名的右方添加符号:(+),则Oracle在连接时则会自动生成一条空记录和表A的记录进行连接)
 
 
 
 
5.外连接的约束:
    A.The outer join operator can appear on only one side of an expression in the join        condition. You get an ORA-1468 error if you attempt to use it on both sides.
 
    B.If a join involves more than two tables, then one table can't be outer joined           with more than one other table in the query.
        Wrong:SELECT E.LNAME, J.FUNCTION, D.NAME
                 FROM EMPLOYEE E, JOB J, DEPARTMENT D
                WHERE E.JOB_ID (+) = J.JOB_ID
                 AND E.DEPT_ID (+) = D.DEPT_ID;
        Correct:CREATE VIEW V_EMP_JOB
                     AS SELECT E.DEPT_ID, E.LNAME, J.FUNCTION
                   FROM EMPLOYEE E, JOB J
                 WHERE E.JOB_ID (+) = J.JOB_ID;
 
                 SELECT V.LNAME, V.FUNCTION, D.NAME
                  FROM V_EMP_JOB V, DEPARTMENT D
                 WHERE V.DEPT_ID (+) = D.DEPT_ID; 
 
        Correct Also:SELECT V.LNAME, V.FUNCTION, D.NAME
                           FROM (SELECT E.DEPT_ID, E.LNAME,J.FUNCTION
                                  FROM EMPLOYEE E, JOB J
                               WHERE E.JOB_ID (+) = J.JOB_ID) V, DEPARTMENT D
                         WHERE V.DEPT_ID (+) = D.DEPT_ID;
 
    C.An outer join condition containing the (+) operator may not use the IN operator.
 
    D.An outer join condition containing the OR operator may not be combined with another    condition using the OR operator.
        SELECT E.LNAME, D.NAME
         FROM EMPLOYEE E, DEPARTMENT D
         WHERE E.DEPT_ID = D.DEPT_ID (+)
           OR D.DEPT_ID = 10;
 
    E.A condition containing the (+) operator may not involve a subquery
        Wrong:SELECT E.LNAME
                FROM EMPLOYEE E
                WHERE E.DEPT_ID (+) = (SELECT DEPT_ID
                                         FROM DEPARTMENT WHERE NAME = ACCOUNTING');
        Correct:SELECT E.LNAME
                  FROM EMPLOYEE E,
                        (SELECT DEPT_ID FROM DEPARTMENT WHERE NAME = 'ACCOUNTING') V
                 WHERE E.DEPT_ID (+) = V.DEPT_ID;
 
 
 
 
 
 
6. 完全外连接(Full Outer Join):
    There are situations when you may want a bidirectional outer join, i.e., you want to include all the rows from A and B that are:
 
    1.From the result of the inner join.
    2.From A that don't have corresponding rows in B.
    3.From B that don't have corresponding rows in A.
 
A UNION of two SELECT statements is a work around for this problem. The UNION operation eliminates duplicate rows, and the result is a full outer join      
Example:
    SELECT D.DEPT_ID, D.NAME, L.REGIONAL_GROUP
     FROM DEPARTMENT D, LOCATION L
     WHERE D.LOCATION_ID (+) = L.LOCATION_ID
    UNION
    SELECT D.DEPT_ID, D.NAME, L.REGIONAL_GROUP
     FROM DEPARTMENT D, LOCATION L
WHERE D.LOCATION_ID = L.LOCATION_ID (+) ;     
 
7.自连接(Self-Join):
There are situations in which one row of a table is related to another row of the same table.Such as:
CREATE TABLE EMPLOYEE (
EMP_ID          NUMBER (4) NOT NULL PRIMARY KEY,
FNAME           VARCHAR2 (15),
LNAME           VARCHAR2 (15),
DEPT_ID         NUMBER (2),
MANAGER_EMP_ID NUMBER (4) REFERENCES EMPLOYEE(EMP_ID),
SALARY          NUMBER (7,2),
HIRE_DATE       DATE,
JOB_ID          NUMBER (3));
To get information about an employee and his manager, you have to join the EMPLOYEE table with itself.
    SELECT E.NAME EMPLOYEE, M.NAME MANAGER
     FROM EMPLOYEE E, EMPLOYEE M
     WHERE E.MANAGER_EMP_ID = M.EMP_ID;
 
Even though the EMPLOYEE table has 14 rows, the previous query returned only 13 rows. This is because there is an employee without a MANAGER_EMP_ID. Oracle excludes this row from the result set while performing the self inner join. To include the employee(s) without a MANAGER_EMP_ID, you need an outer join:
SELECT E.LNAME EMPLOYEE, M.LNAME MANAGER
 FROM EMPLOYEE E, EMPLOYEE M
 WHERE E.MANAGER_EMP_ID = M.EMP_ID (+);
 
 
 
 
 
8.不相等条件的自连接(Self Non-Equi-Joins):
assume that you are in charge of organizing interdepartmental basket ball competition within your company. It is your responsibility to draw the teams and schedule the competition.
SELECT NAME FROM DEPARTMENT;
NAME
--------------
ACCOUNTING
RESEARCH
SALES
OPERATIONS
 
Wrong:SELECT D1.NAME TEAM1, D2.NAME TEAM2
 FROM DEPARTMENT D1, DEPARTMENT D2
        WHERE D1.DEPT_ID != D2.DEPT_ID;
 
TEAM1          TEAM2
-------------- --------------
RESEARCH       ACCOUNTING
SALES          ACCOUNTING
OPERATIONS     ACCOUNTING
ACCOUNTING     RESEARCH
SALES          RESEARCH
OPERATIONS     RESEARCH
ACCOUNTING     SALES
RESEARCH       SALES
OPERATIONS     SALES
ACCOUNTING     OPERATIONS
RESEARCH       OPERATIONS
SALES          OPERATIONS
In this result set, you have permutations such as (RESEARCH, ACCOUNTING) and (ACCOUNTING, RESEARCH), and so on. Therefore, each team plays against the others twice. You need to remove these permutations, which you rightly consider to be duplicates. You think about using DISTINCT. DISTINCT will not help here, because the row (RESEARCH, ACCOUNTING) is different from the row (ACCOUNTING, RESEARCH) from the viewpoint of DISTINCT;
(在这个结果集中,我们对诸如(RESEARCH,ACCOUNTING)和(ACCOUNTING,RESEARCH)的记录进行了位置调换,所以每个队都和其它的队伍进行了两次的比赛。我们必须把那些重复的记录去掉,也许我们会考虑使用DISTINCT,但是在这里DISTINCT不会起作用,因为像(RESEARCH,ACCOUNTING)和(ACCOUNTING,RESEARCH)这样的记录以DISTINCT的观点来看是两条不同的记录)
 
Correct:SELECT D1.NAME TEAM1, D2.NAME TEAM2
         FROM DEPARTMENT D1, DEPARTMENT D2
         WHERE D1.DEPT_ID < D2.DEPT_ID;
 
TEAM1          TEAM2
-------------- --------------
ACCOUNTING     RESEARCH
ACCOUNTING     SALES
RESEARCH       SALES
ACCOUNTING     OPERATIONS
RESEARCH       OPERATIONS
SALES          OPERATIONS
Conceptually, when Oracle executes this query, a Cartesian product is first formed with 16 rows. Then the less-than (<) operator in the join condition restricts the result set to those rows in which the DEPT_ID of Team 1 is less than the DEPT_ID of Team 2. The less-than (<) operator eliminates the duplicates, because for any given permutation of two departments this condition is satisfied for only one. Using greater-than (>) instead of less-than (<) will also give you the required result
 
(理论上来说,当Oracle执行这个查询的时候,首先会产生一个包含了16条记录的笛卡儿积,然后连接条件中的小于号会对返回的记录集进行筛选:返回的记录中Team 1的DEPT_ID必须比Team 2的DEPT_ID小。因为对于诸如(RESEARCH,ACCOUTNING)和(ACCOUTING,RESEARCH)的记录,总会有一条记录满足以上的条件,所以可以去掉重复的记录。使用大于号同样会返回你想要的记录,只不过记录中的队伍顺序调换过来了而已)
 
9.Oracle 9i的JOIN新语法:
Oracle9i introduced new join syntax that is compliant to the ANSI SQL standard defined for SQL/92. Prior to Oracle9i, Oracle supported the join syntax defined in the SQL/86 standard. In addition, Oracle supported outer joins through the proprietary outer join operator (+), discussed earlier in this chapter. The old join syntax and the proprietary outer join operator are still supported in Oracle9i.
 
With the new syntax in Oracle9i, you specify the join type with the JOIN keyword in the FROM clause. For example, to perform an inner join between tables DEPARTMENT and LOCATION, you specify:
 
FROM DEPARTMENT D INNER JOIN LOCATION L
 
In the traditional join syntax, the join condition is specified in the WHERE clause. With the new syntax in Oracle9i, the purpose of the WHERE clause is for filtering only. The join condition is separated from the WHERE clause and put in a new ON clause, which appears as part of the FROM clause. The join condition of the previous example will be specified using the new syntax as:
 
ON D.LOCATION_ID = L.LOCATION_ID;
 
The complete join, using the new syntax, will be:
 
SELECT L.LOCATION_ID, D.NAME, L.REGIONAL_GROUP
FROM DEPARTMENT D INNER JOIN LOCATION L
ON D.LOCATION_ID = L.LOCATION_ID;
 
10.在JOIN中使用USING子句:
Specifying the join condition is further simplified if:

  • You use equi-joins, and
  • The column names are identical in both the tables.
 
 
 
If these two conditions are satisfied, you can apply the new USING clause to specify the join condition. In the previous example, we used an equi-join. Also, the column involved in the join condition (LOCATION_ID) is named identically in both the tables. Therefore, this join condition can also be written as:
 
FROM DEPARTMENT D INNER JOIN LOCATION L USING (LOCATION_ID);
 
The USING clause tells Oracle that the tables in the join have identical names for the column in the USING clause. Now, Oracle merges those two columns and recognizes only one such column. If you have included the join column in the SELECT list, Oracle doesn't allow you to qualify the column with a table name (or table alias). Our SELECT clause, then, needs to appear as follows: The complete syntax with the USING clause will be:
SELECT LOCATION_ID, D.NAME, L.REGIONAL_GROUP
FROM DEPARTMENT D INNER JOIN LOCATION L
USING (LOCATION_ID);
 
The behavior of USING contrasts with the traditional join syntax, in which you must qualify the identical column names with the table name or table alias
 
If a join condition consists of multiple columns, you need to specify all the column conditions in the ON clause separated by AND. For example, if tables A and B are joined based on columns c1 and c2, the join condition would be:
SELECT ...
FROM A INNER JOIN B
ON A.c1 = B.c1 AND A.c2 = B.c2
 
If the column names are identical in the two tables, you can use the USING clause and specify all the columns in one USING clause, separated by commas. The previous join condition can be rewritten as:
SELECT ...
FROM A INNER JOIN B
USING (c1, c2)  
 
11.交叉连接(Cross Join):
An advantage of the new join syntax is that you can't accidentally generate a Cartesian product by omitting join conditions. But what if you really do want a Cartesian product?
SELECT *
FROM A CROSS JOIN B;
The advantage of this new syntax is that it makes your request for a cross join (or Cartesian product) explicit。The new join syntax doesn't allow you to accidentally forget the join condition while performing a join, and thereby helps prevent you from accidentally generating a Cartesian product. When you specify any of the new join keywords in the FROM clause, you tell Oracle that you are going to perform a JOIN, and Oracle insists that you specify the join condition in an ON or USING clause.
 
 
 
 
 
12.ANSI外连接语法:
The ANSI outer join syntax doesn't use the outer join operator (+) in the join condition; rather, it specifies the join type in the FROM clause. The syntax of ANSI outer join is:
 
FROM table1 { LEFT | RIGHT | FULL } [OUTER] JOIN table2
The syntax elements are:
 
table1, table2
Specifies the tables on which you are performing the outer join.
 
LEFT
Specifies that the results be generated using all rows from table1. For those rows in table1 that don't have corresponding rows in table2, NULLs are returned in the result set for the table2 columns. This is the equivalent of specifying (+) on the table2 side of the join condition in the traditional syntax.
 
RIGHT
Specifies that the results be generated using all rows from table2. For those rows in table2 that don't have corresponding rows in table1, NULLs are returned in the result set for the table1 columns. This is the equivalent of specifying (+) on the table1 side of the join condition in the traditional syntax.
 
FULL
Specifies that the results be generated using all rows from table1 and table2. For those rows in table1 that don't have corresponding rows in table2, NULLs are returned in the result set for the table2 columns. Additionally, for those rows in table2 that don't have corresponding rows in table1, NULLs are returned in the result set for the table1 columns. There is no equivalent in the traditional syntax for a FULL OUTER JOIN.
 
OUTER
Specifies that you are performing an OUTER join. This keyword is optional. If you use LEFT, RIGHT, or FULL, Oracle automatically assumes an outer join. The OUTER is for completeness sake, and complements the INNER keyword.
 
13.使用新的JOIN语法的好处:
The new join syntax represents a bit of an adjustment to developers who are used to using Oracle's traditional join syntax, including the outer join operator (+). However, there are several advantages of using the new syntax:
 
A.The new join syntax follows the ANSI standard and therefore makes your code more portable.
B.The new ON and USING clauses help in separating the join conditions from other filter conditions in the WHERE clause. This enhances development productivity and maintainability of your code.
C.The new syntax makes it possible to perform a full outer join without having to perform a UNION of two SELECT queries.

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-247814-1-1.html 上篇帖子: oracle不用安装客户端也可以用plsql远程连接 下篇帖子: Oracle数据库学习之第一篇
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表