sql - GradedJestRisk/db-training GitHub Wiki
SQL, Structured Query Language, is a standard.
SQL does not apply only to relational database. It is a data query language (data themselves doesn't have to be stored in ACID-enforcing system).
Standard is not free and is difficult to read, so consider :
- a book, SQL-92 : "A guide to the SQL standard" by Christopher J. Date ;
- online, SQL-99 : "SQL-99 Complete, Really" .
Data definition language
Data manipulation language
Data ? Language
- UPDATE
- INSERT
- DELETE
- MERGE
Data Query Language:
- SELECT
SELECT COUNT(*)
FROM tableSELECT field, COUNT(*)
FROM table
GROUP BY fieldCOUNT(field) count the rows of the dataset, whose value is not the NULL value
COUNT(*) count the rows of the dataset
If a field contains NULL, DO NOT filter it without IS (NOT) NULL condition.
DO NOT DO THIS!!
AND field <> 1DO THIS
AND IS NOT NULL AND field1 <> 1Using vendor-alternatives, like NVL() in Oracle may cause problems because of special values
eg: NVL(field1, 0, field1) <> 1
It may work now, but as soon as developer will use 0 in a row, it will break..
Difference with subqueries:
- readibility;
- performance.
Also, avoid switching to procedural (than can imply performance loss) because of query complexity without it.
Example
For each employee:
- manager name;
- how many other people are in their department ?
SELECT e.ename AS employee_name,
dc1.dept_count AS emp_dept_count,
m.ename AS manager_name,
dc2.dept_count AS mgr_dept_count
FROM emp e
JOIN (SELECT deptno, COUNT(*) AS dept_count
FROM emp
GROUP BY deptno) dc1
ON e.deptno = dc1.deptno
JOIN emp m ON e.mgr = m.empno
JOIN (SELECT deptno, COUNT(*) AS dept_count
FROM emp
GROUP BY deptno) dc2
ON m.deptno = dc2.deptno;WITH dept_count AS (
SELECT deptno, COUNT(*) AS dept_count
FROM emp
GROUP BY deptno)
SELECT e.ename AS employee_name,
dc1.dept_count AS emp_dept_count,
m.ename AS manager_name,
dc2.dept_count AS mgr_dept_count
FROM emp e
JOIN dept_count dc1 ON e.deptno = dc1.deptno
JOIN emp m ON e.mgr = m.empno
JOIN dept_count dc2 ON m.deptno = dc2.deptno;So we don't need to redefine the same subquery multiple times. Instead we just use the query name defined in the WITH clause, making the query much easier to read.
If the contents of the WITH clause is sufficiently complex, Oracle may decide to resolve the result of the subquery into a global temporary table. This can make multiple references to the subquery more efficient
Can use multiple subqueries using renaming
WITH
src_done AS (SELECT id FROM source WHERE status = 'DONE'),
src_valid AS (SELECT id FROM source WHERE status <> 'CANCEL' AND cancel_date < SYSDATE)
SELECT
(...)
FROM data
WHERE data.id IN (src_done.id, src_valid.id) Can use it including INSERT INTO
INSERT INTO <TARGET TABLE>
WITH
source AS (.. FROM <SOURCE>..)
SELECT
(..)
FROM
<INTERMEDIATE> INNER JOIN source (..)These are equivalent, but ON doesn't work if:
- column names are not the same in the two tables;
- you want to use the joining column in SELECT
SELECT e.ename, d.dname
FROM emp e JOIN dept d USING (deptno);
SELECT e.ename, d.dname
FROM emp e JOIN dept d ON d.deptno = e.deptno;Data Control Language
Grant, REVOKE