JOIN[1] | Join Type | SQL SYNTAX EXAMPLE | DESCRIPTION |
CROSS | CROSS JOIN | SELECT * FROM T1, T2 | Returns the Cartesian product of T1 and T2 (old style). |
SELECT * FROM T1 CROSS JOIN T2 | Returns the Cartesian product of T1 and T2. | ||
INNER | Old-Style JOIN | SELECT * FROM T1, T2 WHERE T1.C1 = T2.C1 | Returns only the rows that meet the join condition in the WHERE clause (old style). Only rows with matching values are selected. |
NATURAL JOIN | SELECT * FROM T1, T2 WHERE T1 NATURAL JOIN T2 | Returns only the rows that meet the join condition in the WHERE clause(old style). Only rows with matching values are selected. | |
JOIN USING | SELECT * FROM T1 JOIN T2 USING (C1) | Returns only the rows with matching values in the columns indicated in the USING clause. | |
JOIN ON | SELECT * FROM T1 JOIN T2 ON T1.C1 = T2.C1 | Returns only the rows that meet the join condition indicated in the ON clause. | |
OUTER | LEFT JOIN | SELECT * FROM T1 LEFT OUTER JOIN T2 ON T1.C1 = T2.C1 | Returns rows with matching values and includes all rows from the left table (T1) with unmatched values. |
RIGHT JOIN | SELECT * FROM T1 RIGHT OUTER JOIN T2 ON T1.C1 = T2.C1 | Returns rows with matching values and includes all rows from the right table (T2) with unmatched values. | |
FULL JOIN | SELECT * FROM T1 FULL OUTER JOIN T2 ON T1.C1 = T2.C1 | Returns rows with matching values and includes all rows from both tables (T1 and T2) with unmatched values. |
JOIN[1] | Join Type | SQL SYNTAX EXAMPLE | DESCRIPTION |
OUTER | LEFT JOIN | SELECT * FROM T1 LEFT OUTER JOIN T2 ON T1.C1 = T2.C1 | Returns rows with matching values and includes all rows from the left table (T1) with unmatched values. |
RIGHT JOIN | SELECT * FROM T1 RIGHT OUTER JOIN T2 ON T1.C1 = T2.C1 | Returns rows with matching values and includes all rows from the right table (T2) with unmatched values. | |
FULL JOIN | SELECT * FROM T1 FULL OUTER JOIN T2 ON T1.C1 = T2.C1 | Returns rows with matching values and includes all rows from both tables (T1 and T2) with unmatched values. |
SELECT PCODE, VENDOR.V_CODE, V_NAME
FROM VENDOR FULL JOIN PRODUCT ON VENDOR.V_CODE = PRODUCT.V_CODE;
Results are shown in Figure 8.12
SELECT P_CODE, P_PRICE FROM PRODUCT
WHERE P_PRICE >= (SELECT AVG(P_PRICE) FROM PRODUCT);
SELECT DISTINCT CUS_CODE, CUS_LNAME, CUS_FNAME
FROM CUSTOMER JOIN INVOICE USING (CUS_CODE)
JOIN LINE USING (INU_NUMBER)
JOIN PRODUCT USING (P_CODE)
WHERE P_CODE IN (SELECT P_CODE FROM PRODUCT WHERE P_DESCRIPT = 'Claw hammer');
SELECT DISTINCT CUS_CODE, CUS_LNAME, CUS_FNAME
FROM CUSTOMER JOIN INVOICE USING (CUS_CODE)
JOIN LINE USING (INU_NUMBER)
JOIN PRODUCT USING (P_CODE)
WHERE P_CODE IN (SELECT P_CODE FROM PRODUCT WHERE P_DESCRIPT LIKE '%hammer%' OR P_DESCRIPT LIKE '%saw%');
SELECT P_CODE, SUM(LINE_UNITS)
FROM LINE
GROUP BY P_CODE
HAVING SUM(LINE_UNITS) > (SELECT AVG(LINE_UNITS) FROM LINE);
SELECT P_CODE, P_QOH*P_PRICE
FROM PRODUCT
WHERE P_QOH*P_PRICE > ALL
(SELECT P_QOH*P_PRICE FROM PRODUCT
WHERE V_CODE IN (SELECT V_CODE FROM VENDOR WHERE V_STATE='FL'));
SELECT DISTINCT CUSTOMER.CUS_CODE, CUSTOMER.CUS_LNAME
FROM CUSTOMER,
(SELECT INVOICE.CUS_CODE
FROM INVOICE NATURAL JOIN LINE WHERE P_CODE = '13-Q2/P2') CP1, (SELECT INVOICE.CUS_CODE
FROM INVOICE NATURAL JOIN LINE WHERE P_CODE = '23109-HB') CP2
WHERE CUSTOMER.CUS_CODE = CP1.CUS_CODE AND
CP1.CUS_CODE = CP2.CUS_CODE;
SELECT P_CODE, P_PRICE, (SELECT AVG(P_PRICE) FROM PRODUCT) AS AVGPRICE, P_PRICE-(SELECT AVG(P_PRICE) FROM PRODUCT) AS DIFF
FROM PRODUCT;
SELECT P_CODE, SUM(LINE_UNITS*LINE_PRICE) AS SALES,
(SELECT COUNT(*) FROM EMPLOYEES) AS ECOUNT,
SUM(LINE_UNITS*LINE_PRICE)/(SELECT COUNT(*) FROM EMPLOYEE) AS CONTRID
FROM LINE
GROUP BY P_CODE;
Until now, all subqueries you have learned execute independently. That is, each subquery in a command sequence executes in a serial fashion, one after another. The inner subquery executes first; its output is used by the outer query, which then executes until the last outer query executes (the first SQL statement in the code).
In contrast, a correlated subquery is a subquery that executes once for each row in the outer query. That process is similar to the typical nested loop in a programming language. For example:
FOR X = 1 TO 2
FOR Y = 1 TO 3
PRINT “X = “X, “Y = “Y END
END
END
The relational DBMS uses the same sequence to produce correlated subquery results:
SELECT INV_NUMBER, P_CODE, LINE_UNITS
FROM LINE LS
WHERE LS.LINE_UNITS >
(SELECT AVG(LINE_UNITS)
FROM LINE LA
WHERE LA.P_CODE = LS.P_CODE);
SELECT INV_NUMBER, P_CODE, LINE_UNITS,
(SELECT AVG(LINE_UNITS) FROM LINE LX WHERE LX.P_CODE = LS.P_CODE) AS AVG
FROM LINE LS
WHERE LS.LINE UNITS >
(SELECT AVG(LINE_UNITS)
FROM LINE LA
WHERE LA.P_CODE = LS.P_CODE);
Syntax | ||
UNION | query UNION query UNION ALL | Combines rows from two or more queries without including duplicate rows
UNION ALL: - Produces a relation that retains duplicate rows
- Can be used to unite more than two queries
|
INTERSECT | query INTERSECT query | Combines rows from two queries, returning only the rows that appear in both sets IN and NOT IN subqueries can be used in place of INTERSECT |
Except (MINUS) |
query EXCEPT query query MINUS query | Combines rows from two queries and returns only the rows that appear in the first set |
statement | command | |
CREATE VIEW | Data definition command that stores the subquery specification in the data dictionary | CREATE VIEW viewname AS SELECT query |
Updatable Views | Used to update attributes in any base tables used in the view |
CREATE VIEW PRICEGT50 AS
SELECT P_DESCRIPT, P_QOH, P_PRICE
SELECT PRODUCT
SELECT P_PRICE > 50.00;
SELECT * FROM PRICEGT50;
CREATE VIEW PSUUPD AS (
SELECT PRODMASTER.PROD_ID, PROD_QOH, PS_QTY
FROM PRODMASTER, PRODSALES
WHERE PRODMASTER.PROD_ID = PRODSALES.PROD_ID);
SELECT * FROM PSVUPD;
UPDATE PSUUPD
SET PROD_QOH = PROD_QOH - PS_QTY;
SELECT * FROM PRODMASTER;
CREATE SEQUENCE CUS_CODE_SEQ START WITH 20010 NOCACHE;
CREATE SEQUENCE INU_NUMBER_SEQ START WITH 4010 NOCACHE;
SELECT * FROM USER_SEQUENCES;
INSERT INTO CUSTOMER VALUES (CUS_CODE_SEQ.NEXTVAL, 'Connery', 'Sean', NULL, '615', '898-2007', 0.00);
SELECT * FROM CUSTOMER WHERE CUS_CODE = 20010;
INSERT INTO INVOICE
VALUES (INU_NUMBER_SEQ.NEXTVAL, 20010, SYSDATE);
SELECT * FROM INVOICE WHERE INU_NUMBER = 4010;
INSERT INTO LINE
VALUES (INU_NUMBER_SEQ.CURVAL, 1, '13-02/P2', 1, 14.99);
INSERT INTO LINE
VALUES (INU_NUMBER_SEQ.CURVAL, 2, '23109-HB', 1, 9.95);
SELECT FROM LINE WHERE INU_NUMBER = 4010;
COMMIT;
BEGIN
INSERT INTO VENDOR
VALUES (25678, 'Microsoft Corp.', 'Bill Gates', '765', '546-8484', 'WA', 'N');
END;
/
SET SERVEROUTPUT ON
BEGIN
INSERT INTO VENDOR
VALUES (25572, 'Clue Store', 'Issac Hayes', '456', '323-2009', 'VA', 'N');
DBMS_OUTPUT.PUT_LINE('New Vendor Added!');
END;
/
SELECT * FROM VENDOR;
DATA TYPE | DESCRIPTION |
CHAR | Character values of a fixed length; for example: W_ZIP CHAR(5) |
VARCHAR2 | Variable length character values; for example: W_FNAME VARCHAR2(15) |
NUMBER | Numeric values; for example: W_PRICE NUMBER(6,2) |
DATE | Date values; for example: W_EMP_DOB DATE |
%TYPE | Inherits the data type from a variable that you declared previously or from an attribute of a database table; for example: W_PRICE PRODUCT.P_PRICE%TYPE Assigns W_PRICE the same data type as the P_PRICE column in the PRODUCT table |
NAME OF FUNCTION | FUNCTION | SYNTAX | EXAMPLE |
Creating Triggers | Creating Triggers | CREATE [OR REPLACE ] TRIGGER trigger_name {BEFORE | AFTER | INSTEAD OF } {INSERT [OR] | UPDATE [OR] | DELETE} [OF col_name] ON table_name [FOR EACH ROW] DECLARE [variable_namedata type[:=initial_value]] BEGIN PL/SQL instructions; ...... END; | CREATE OR REPLACE TRIGGER TRG_PRODUCT_REORDER AFTER INSERT OR UPDATE OF P_QOH ON PRODUCT BEGIN UPDATE PRODUCT SET P_REORDER = 1 WHERE P_QOH <= P_MIN END; / |
Triggering a Trigger | Triggering a Trigger | [perform some DML operations] | INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY) VALUES (7, 'Kriti', 22, 'HP', 7500.00 ); |
Deletes a trigger | ... without deleting the table | DROP TRIGGER trigger_name | Trigger action based on DML predicates - Actions depend on the type of DML statement that fires the trigger |
{BEFORE | AFTER | INSTEAD OF } {INSERT [OR] | UPDATE [OR] | DELETE} [OF col_name] ON table_name [REFERENCING OLD AS o NEW AS n] [FOR EACH ROW]
WHEN (condition) DECLARE Declaration-statements
BEGIN Executable-statements EXCEPTION Exception-handling-statements
END;
CREATE OR REPLACE TRIGGER display_salary_changes BEFORE DELETE OR INSERT OR UPDATE ON customers FOR EACH ROW
WHEN (NEW.ID > 0)
DECLARE
sal_diff number;
BEGIN
sal_diff := :NEW.salary - :OLD.salary;
dbms_output.put_line('Old salary: ' || :OLD.salary);
dbms_output.put_line('New salary: ' || :NEW.salary);
dbms_output.put_line('Salary difference: ' || sal_diff);
END;
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">When a record is created in CUSTOMERS table, above created trigger display_salary_changes will be fired and it will display the following result:</span>
Old salary:
CREATE OR REPLACE PROCEDURE <em>procedure_name</em> [(<em>argument</em> [IN/OUT] <em>data-type</em>,