SlideShare a Scribd company logo
1 of 213
Download to read offline
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.
SQLThe meanest, fastest thing out there
Connor McDonald
2
Copyright © 2018, Oracle and/or its affiliates. All rights reserved.
Connor McDonald
Copyright © 2018, Oracle and/or its affiliates. All rights reserved. |Copyright © 2018, Oracle and/or its affiliates. All rights reserved. |
4
Copyright © 2018, Oracle and/or its affiliates. All rights reserved. |Copyright © 2018, Oracle and/or its affiliates. All rights reserved. |
5
Copyright © 2018, Oracle and/or its affiliates. All rights reserved. |
Stuff
youtube bit.ly/youtube-connor
blog bit.ly/blog-connor
twitter bit.ly/twitter-connor
400+ posts mainly on database & development
250 technical videos, new uploads every week
rants and raves on tech and the world :-)
Copyright © 2018, Oracle and/or its affiliates. All rights reserved.
etc...
facebook bit.ly/facebook-connor
linkedin bit.ly/linkedin-connor
instagram bit.ly/instagram-connor
slideshare bit.ly/slideshare-connor
Copyright © 2018, Oracle and/or its affiliates. All rights reserved. |Copyright © 2018, Oracle and/or its affiliates. All rights reserved. |
https://asktom.oracle.com
9
SO
THE
BIG
QUESTION
IS
15
WHY ?
why talk about SQL ?
16
after all ...
17
18
why talk about SQL # 1
19
NoSQL
20
non relational
21
why talk about SQL # 2
22
developers love cool stuff
23
MICROSERVICES
24
SQL is microservices !
25
26
"fine-grained to perform a single function"
"Each service is ... minimal, and complete"
https://en.wikipedia.org/wiki/Microservices
select COUNT(*)
from PEOPLE
where GENDER = 'MALE'
even cooler stuff
27
API
28
SQL is entirely APIs !
29
30
"By abstracting the underlying implementation"
"describes the expected behaviour ... but can have multiple implementations"
https://en.wikipedia.org/wiki/Application_programming_interface
select NAME, STREET_NO, ZIP_CODE
from PEOPLE p,
ADDRESS a
where p.AGE > 50
and p.ADDRESS_ID = a.ADDRESS_ID;
why talk about SQL # 3
31
developers
32
code for functionality ...
33
... yet we end up data processing :-(
34
35
key point
36
this session is not about ...
37
being a smart-ass
38
we can do anything ...
39
SQL> with x( s, ind ) as
2 ( select sud, instr( sud, '.' )
3 from ( select replace(replace(
4 replace(replace(:board,'-'),'|'),' '),chr(10)) sud
5 from dual )
6 union all
7 select substr(s,1,ind-1)||z||substr(s,ind+1)
8 , instr(s,'.',ind+1)
9 from x
10 , ( select to_char( rownum ) z
11 from dual connect by rownum <= 9 ) z
12 where ind > 0
13 and not exists (
14 select null
15 from ( select rownum lp from dual
16 connect by rownum <= 9 )
17 where z = substr(s,trunc((ind-1)/9)*9+lp,1)
40
18 or z = substr(s,mod(ind-1,9)-8+lp*9,1)
19 or z = substr(s,mod(trunc((ind-1)/3),3)*3
20 +trunc((ind-1)/27)*27+lp
21 +trunc((lp-1)/3)*6,1)
22 )
23 ),
24 result as (
25 select s
26 from x
27 where ind = 0 )
28 select
29 regexp_replace(substr(s,(idx-1)*9+1,9),
30 '(...)(...)(...)',
31 '1|2|3')||
32 case when mod(idx,3)=0 then chr(10)||rpad('-',11,'-') end soln
33 from result,
34 ( select level idx
35 from dual
36 connect by level <= 9 )
41
Ack: Anton Scheffer,
https://technology.amis.nl
SQL> variable board varchar2(1000)
SQL> begin :board :=
2 '53.|.7.|...
3 6..|195|...
4 .98|...|.6.
5 -----------
6 8..|.61|..3
7 4..|8.3|..1
8 7..|.2.|..6
9 -----------
10 .6.|...|28.
11 ...|419|..5
12 ...|.8.|.79
13 ';
14 end;
42
5 3 7
6 1 9 5
9 8 6
8 6 1 3
4 8 3 1
7 2 6
6 2 8
4 1 9 5
8 7 9
SOLUTION
-----------
534|678|912
672|195|348
198|342|567
-----------
859|761|423
426|853|791
713|924|856
-----------
961|537|284
287|419|635
345|286|179
-----------
43
sud.sql
44
100%
% of developers that
will need to solve Sudoku
as part of their job
45
100%
% of developers that need
to get real stuff done
real stuff
46
47
1
some controversy...
48
49
DBA
51Public
52Public
DBA friendship is important
53
oc00.sql
54
2
totals / subtotals
55
"Employee salary list,
plus department total,
plus grand total"
56
57
SQL> select empno, ename, sal, deptno from emp
2 order by deptno;
EMPNO ENAME SAL DEPTNO
---------- ---------- ---------- ----------
7782 CLARK 2450 10
7839 KING 5000 10
7934 MILLER 1300 10
...
7900 JAMES 950 30
7698 BLAKE 2850 30
7654 MARTIN 1250 30
58
SQL> select deptno,
2 sum(sal)
3 from emp
4 group by deptno
5 order by deptno;
DEPTNO SUM(SAL)
---------- ----------
10 8750
20 10875
30 9400
SQL> select sum(sal) from emp;
SUM(SAL)
----------
29025
from 3 to 2
59
rollup
SQL> select empno, ename, sal, deptno from emp
2 order by deptno;
EMPNO ENAME SAL DEPTNO
---------- ---------- ---------- ----------
7782 CLARK 2450 10
7839 KING 5000 10
7934 MILLER 1300 10
...
7900 JAMES 950 30
7698 BLAKE 2850 30
7654 MARTIN 1250 30
60
SQL> select deptno,
2 sum(sal)
3 from emp
4 group by rollup(deptno)
5 order by deptno;
DEPTNO SUM(SAL)
---------- ----------
10 8750
20 10875
30 9400
29025
still messy...
61
EMPNO SAL DEPTNO
---------- ---------- ----------
7782 2450 10
7839 5000 10
7934 1300 10
7566 2975 20
7902 3000 20
7876 1100 20
7369 800 20
62
DEPTNO SUM(SAL)
---------- ----------
10 8750
20 10875
30 9400
29025
7782 2450 10
7839 5000 10
7934 1300 10
7566 2975 20
10 8750
from 2 to 1
63
SQL> select deptno,
2 nvl2(rownum,max(empno),null) empno,
3 nvl2(rownum,max(ename),null) ename,
4 sum(sal)
5 from emp
6 group by rollup(deptno,rownum)
7 order by deptno,empno;
DEPTNO EMPNO ENAME SUM(SAL)
---------- ---------- ---------- ----------
10 7782 CLARK 2450
10 7839 KING 5000
10 7934 MILLER 1300
10 8750
20 7369 SMITH 800
20 7566 JONES 2975
...
30 7900 JAMES 950
30 9400
2902564
all totals are possible
65
SQL> select deptno,job,sum(sal) from scott.emp
2 group by CUBE(deptno,job)
3 order by deptno,job;
DEPTNO JOB SUM(SAL)
---------- --------- ----------
10 CLERK 1300
10 MANAGER 2450
10 PRESIDENT 5000
10 8750
20 ANALYST 6000
20 CLERK 1900
20 MANAGER 2975
20 10875
30 CLERK 950
30 MANAGER 2850
30 SALESMAN 5600
30 9400
ANALYST 6000
CLERK 4150
MANAGER 8275
PRESIDENT 5000
SALESMAN 5600
29025
66
totally customisable
67
SQL> select deptno, job, mgr, sum(sal) from emp
2 group by grouping sets (
3 (deptno),
4 (job,mgr), () ) ;
DEPTNO JOB MGR SUM(SAL)
---------- --------- ---------- ----------
CLERK 7902 800
PRESIDENT 5000
CLERK 7698 950
CLERK 7788 1100
CLERK 7782 1300
SALESMAN 7698 5600
MANAGER 7839 8275
ANALYST 7566 6000
10 8750
20 10875
30 9400
29025
68
69
3
query block naming
70
C#, C++ ESB Tuxedo
Weblogic
Stored
Procedure
71
for (int i = 0; i < WinningCombinations.Count; ++i)
{
if (WinningCombinations[i].Investment > 0 &&
WinningCombinations[i].PrimaryDividend > MinDividendDeadHeat)
{
maxDivisor =
Math.Max(maxDivisor, WinningCombinations[i].Divisor);
}
}
for (int i = 0; i < WinningCombinations.Count; ++i)
{
if (WinningCombinations[i].Investment > 0 &&
WinningCombinations[i].PrimaryDividend > MinDividendDeadHeat)
{
WinningCombinations[i].Divisor =
maxDivisor / WinningCombinations[i].Divisor;
sumNewDivisors += WinningCombinations[i].Divisor;
}
}72
no comments
73
74
"C# is self-documenting"
75
"uh huh"
76
SQL can be complex
77
SQL should "self document"
78
query blocks =
self documenting SQL
79
select emp.*
from emp,
( select trunc(hiredate,'YYYY'), max(empno) empno
from emp
where empno > 0
group by trunc(hiredate,'YYYY') ) x,
( select deptno, avg(sal)
from emp
group by deptno ) y
where x.empno = emp.empno
and y.deptno = emp.deptno
80
Id | Operation | Name |
----------------------------------------------|
0 | SELECT STATEMENT | |
1 | HASH JOIN | |
2 | TABLE ACCESS BY INDEX ROWID | EMP |
3 | NESTED LOOPS | |
4 | VIEW | |
5 | SORT GROUP BY | |
6 | TABLE ACCESS BY INDEX ROWID| EMP |
7 | INDEX FULL SCAN | E2 |
8 | INDEX RANGE SCAN | E1 |
9 | VIEW | |
10 | SORT GROUP BY | |
11 | TABLE ACCESS BY INDEX ROWID | EMP |
12 | INDEX RANGE SCAN | E2 |
81
?
82
select emp.*
from emp,
( select trunc(hiredate,'YYYY'), max(empno) empno
from emp
where empno > 0
group by trunc(hiredate,'YYYY') ) x,
( select deptno, avg(sal)
from emp
group by deptno ) y
where x.empno = emp.empno
and y.deptno = emp.deptno
Id | Operation | Name |
----------------------------------------------|
0 | SELECT STATEMENT | |
1 | HASH JOIN | |
2 | TABLE ACCESS BY INDEX ROWID | EMP |
3 | NESTED LOOPS | |
4 | VIEW | |
5 | SORT GROUP BY | |
6 | TABLE ACCESS BY INDEX ROWID| EMP |
7 | INDEX FULL SCAN | E2 |
8 | INDEX RANGE SCAN | E1 |
9 | VIEW | |
10 | SORT GROUP BY | |
11 | TABLE ACCESS BY INDEX ROWID | EMP |
12 | INDEX RANGE SCAN | E2 |
select emp.*
from emp,
( select /*+ QB_NAME(YR_HIRE) */
trunc(hiredate,'YYYY'), max(empno) empno
from emp
where empno > 0
group by trunc(hiredate,'YYYY') ) x,
( select /*+ QB_NAME(AV_SAL) */
deptno, avg(sal)
from emp
group by deptno ) y
where x.empno = emp.empno
and y.deptno = emp.deptno
83
select emp.*
from emp,
( select /*+ QB_NAME(YR_HIRE) */
trunc(hiredate,'YYYY'), max(empno) empno
from emp
where empno > 0
group by trunc(hiredate,'YYYY') ) x,
( select /*+ QB_NAME(AV_SAL) */
deptno, avg(sal)
from emp
group by deptno ) y
where x.empno = emp.empno
and y.deptno = emp.deptno
Id | Operation | Name | Query Block
----------------------------------------------|--------------
0 | SELECT STATEMENT | |
1 | HASH JOIN | |
2 | TABLE ACCESS BY INDEX ROWID | EMP |
3 | NESTED LOOPS | |
4 | VIEW | |
5 | SORT GROUP BY | |
6 | TABLE ACCESS BY INDEX ROWID| EMP |
7 | INDEX FULL SCAN | E2 |
8 | INDEX RANGE SCAN | E1 |
9 | VIEW | |
10 | SORT GROUP BY | |
11 | TABLE ACCESS BY INDEX ROWID | EMP |
12 | INDEX RANGE SCAN | E2 |
SEL$1
SEL$1
AV_SAL
AV_SAL
AV_SAL
AV_SAL
SEL$1
YR_HIRE
YR_HIRE
YR_HIRE
YR_HIRE
84
85
4
error logging
86
SQL> insert into MY_TABLE
2 select *
3 from MY_HUGE_GREAT_FAT_TABLE;
87
MY_HUGE_GREAT_FAT_TABLE;
88
89
90
91
92
SQL> insert into MY_TABLE
2 select *
3 from MY_HUGE_GREAT_FAT_TABLE;
Elapsed: 06:12:34.00
93
SQL> insert into MY_TABLE
2 select *
3 from MY_HUGE_GREAT_FAT_TABLE;
Elapsed: 06:12:34.00
ERROR at line 1:
ORA-01847: day of month must be between 1 and last day of month
94
95
96
97
and then we do this :-)
SQL> select count(*) from MY_TABLE;
COUNT(*)
----------
0
98
what we want
99
keep successful rows
100
skip / bypass bad rows
101
hard
102
SQL> insert into MY_TABLE
2 select *
3 from MY_HUGE_GREAT_FAT_TABLE
4 where "not a duplicate"
5 and "datatypes are ok"
6 and "foreign keys are ok"
7 and "check constraints are ok"
103
SQL> exec DBMS_ERRLOG.CREATE_ERROR_LOG('EMP')
104
ERR$_EMP
105
DBMS_ERRLOG.CREATE_ERROR_LOG (
dml_table_name IN VARCHAR2,
err_log_table_name IN VARCHAR2 := NULL,
err_log_table_owner IN VARCHAR2 := NULL,
...
106
SQL> desc ERR$_EMP
Name Null? Type
----------------------------- -------- ----------------
ORA_ERR_NUMBER$ NUMBER
ORA_ERR_MESG$ VARCHAR2(2000)
ORA_ERR_ROWID$ ROWID
ORA_ERR_OPTYP$ VARCHAR2(2)
ORA_ERR_TAG$ VARCHAR2(2000)
EMPNO VARCHAR2(4000)
ENAME VARCHAR2(4000)
JOB VARCHAR2(4000)
MGR VARCHAR2(4000)
HIREDATE VARCHAR2(4000)
SAL VARCHAR2(4000)
COMM VARCHAR2(4000)
DEPTNO VARCHAR2(4000)
107
108
example
109
add to EMP from NEW_DATA
110
SQL> select * from NEW_DATA;
EMPNO SAL DEPTNO
---------- ---------- ----------
1000 5000 20
100X 3550 10
2000 2500 50
7934 4000 20
111
non-numeric
no dept 50
duplicate
SQL> exec dbms_errlog.create_error_log( 'EMP' );
PL/SQL procedure successfully completed.
SQL> insert into EMP (empno,sal,deptno)
2 select empno,sal,deptno
3 from NEW_DATA
4 LOG ERRORS REJECT LIMIT UNLIMITED;
1 row created.
112
50
SQL> select ORA_ERR_OPTYP$ op, ORA_ERR_MESG$, EMPNO
2 from ERR$_EMP
OP ORA_ERR_MESG$ EMPNO
-- ------------------------------------------------------------ -----
I ORA-01722: invalid number 100X
I ORA-02291: integrity constraint (SCOTT.FK_DEPTNO) violated 2000
I ORA-00001: unique constraint (SCOTT.PK_EMP) violated 7934
113
114
5
partitioned outer join
115
116
SQL> select *
2 from timeslots;
HR
--
8
9
10
11
12
13
14
15
16
SQL> select *
2 from bookings;
HR ROOM WHO
------- ---------- -------
8 Room2 PETE
9 Room1 JOHN
11 Room1 MIKE
14 Room2 JILL
15 Room2 JANE
16 Room1 SAM
bookings by hour
117
conventional outer join
118
SQL> SELECT hrs.hr, t1.room, t1.who
2 from timeslots hrs
3 left outer join bookings t1
4 on hrs.hr = t1.hr
5 order by 1
HR ROOM WHO
------- ---------- ----------
8 Room2 PETE
9 Room1 JOHN
10
11 Room1 MIKE
12
13
14 Room2 JILL
15 Room2 JANE
16 Room1 SAM
118
bookings by hour per room
119
120
HR ROOM WHO
------- ---------- ----------
8 Room2 PETE
9
10
11
12
13
14 Room2 JILL
15 Room2 JANE
16
HR ROOM WHO
------- ---------- ----------
8
9 Room1 JOHN
10
11 Room1 MIKE
12
13
14
15
16 Room1 SAM
121
SQL> select *
2 from timeslots;
HR
--
8
9
10
11
12
13
14
15
16
x "Room 1"
x "Room 2"
...
x "Room n"
partitioned outer join
122
SQL> SELECT hrs.hr, t1.room, t1.who
2 FROM bookings t1
3 PARTITION BY (t1.room)
4 RIGHT OUTER JOIN timeslots ON (hrs.hr = t1.hr)
5 order by 1,2
HR ROOM WHO
--------- ---------- ----------
8 Room1
9 Room1 JOHN
10 Room1
11 Room1 MIKE
12 Room1
13 Room1
14 Room1
15 Room1
16 Room1 SAM
8 Room2 PETE
9 Room2
10 Room2
11 Room2
12 Room2
13 Room2
14 Room2 JILL
15 Room2 JANE
16 Room2 123
124
6
subquery factoring
125
common table expressions
126
WITH clause
127
SQL> WITH last_hire AS
2 ( select deptno, max(hiredate)
3 from emp
4 group by deptno
5 )
6 select * from last_hire;
DEPTNO MAX(HIRED
---------- ---------
30 03-DEC-81
20 12-JAN-83
10 23-JAN-82
128
"who cares?....... more code, same result"
129
WITH last_hire AS
(
select deptno, max(hiredate)
from emp
group by deptno
)
select * from last_hire;
130
why is it cool ?
131
good solution metaphor
132
relational is a rigorous model ...
133
relational is the dominant model ...
134
relational ... can sortta suck
135
not our fault
136
Codd & Date
137
"data is represented as mathematical n-ary
relations, an n-ary relation being a subset of the
Cartesian product of n domains."
138
139
procedural world
140
step by step
141
"First, get the total salary paid by each department,
then get the average of these totals,
then list those departments above that average"
142
SQL ?
"First, get the total salary paid by department...
SQL> WITH dept_salaries AS (
2 SELECT dname, SUM(sal) dept_sal
3 FROM emp e, dept d
4 WHERE e.deptno = d.deptno
5 GROUP BY dname),
143
"...then get the average of these totals...
6 avg_sal AS ( SELECT AVG(dept_sal) avsal
7 FROM dept_salaries)
144
"...then list those departments above average."
8 SELECT * FROM dept_salaries d, avg_sal a
9 WHERE d.dept_sal > a.avsal
10 ORDER BY d.dname;
145
SQL> WITH dept_salaries AS (
2 SELECT dname, SUM(sal) dept_sal
3 FROM emp e, dept d
4 WHERE e.deptno = d.deptno
5 GROUP BY dname),
6 avg_sal AS ( SELECT AVG(dept_sal) avsal
7 FROM dept_salaries)
8 SELECT * FROM dept_salaries d, avg_sal a
9 WHERE d.dept_sal > a.avsal
10 ORDER BY d.dname;
146
programmer's approach....
147
... relational solution
148
the "finishing touches"
149
everyone loves JSON
150
recall: partitioned outer join
151
152
SQL> with raw_data as (
2 select
3 hrs.hr,
4 t1.room,
5 t1.who
6 from bookings t1
7 partition by (t1.room)
8 right outer join hrs
9 on (hrs.hr = t1.hr)
10 order by
11 hr, room
12 )
13 select
14 json_arrayagg(
15 json_object(key room||to_char(hr) value who )
16 order by hr ) as meetings
17 from raw_data ;
[{"Room1-08":null},
{"Room1-09":"JOHN"},
{"Room1-10":null},
{"Room1-11":"MIKE"},
{"Room1-12":null},
...
...
{"Room2-14":"JILL"},
{"Room2-15":null},
{"Room2-16":"JANE"}]
153
7
pagination
154
155
"employees by hiredate, recent first"
SQL> select empno, ename, hiredate
2 from emp
3 where rownum <= 5
4 order by hiredate desc;
EMPNO ENAME HIREDATE
---------- ---------- -------------------
7654 MARTIN 28/09/1981 00:00:00
7566 JONES 02/04/1981 00:00:00
7521 WARD 22/02/1981 00:00:00
7499 ALLEN 20/02/1981 00:00:00
7369 SMITH 17/12/1980 00:00:00
156
inline view
157
SQL> select *
2 from (
3 select empno, ename, hiredate
4 from emp
5 order by hiredate desc
6 )
7 where rownum <= 5;
EMPNO ENAME HIREDATE
---------- ---------- ---------
7876 ADAMS 12-JAN-83
7788 SCOTT 09-DEC-82
7934 MILLER 23-JAN-82
7900 JAMES 03-DEC-81
7902 FORD 03-DEC-81
158
SQL> select *
2 from (
3 select
4 empno, ename, hiredate,
5 row_number() over ( order by hiredate desc) rn
6 from emp
7 )
8 where rn <= 5;
159
SQL> select empno, ename, hiredate
2 from emp
3 order by hiredate desc
4 fetch first 5 rows only;
EMPNO ENAME HIREDATE
---------- ---------- ---------
7876 ADAMS 12-JAN-83
7788 SCOTT 09-DEC-82
7934 MILLER 23-JAN-82
7900 JAMES 03-DEC-81
7902 FORD 03-DEC-81
160
161
"TL;DR ... my app can do it"
public static void Paging(Connection conn ) throws Exception
{
PreparedStatement sql_stmt =
conn.prepareStatement(
"select empno, ename, hiredate
from emp
order by hiredate desc");
ResultSet rset = sql_stmt.executeQuery();
int i = 0;
while( rset.next() )
{
...
i = i + 1;
if (i > 5) {
break;
}
}
rset.close();
}
162
demo
164
oc01.sql
let the database know
165
SQL> select *
2 from (
3 select empno, ename, hiredate
4 from emp
5 order by hiredate desc
6 )
7 where rownum <= 5;
166
------------------------------------------------
| Id | Operation | Name | Rows |
------------------------------------------------
| 0 | SELECT STATEMENT | | 5 |
|* 1 | COUNT STOPKEY | | |
| 2 | VIEW | | 14 |
|* 3 | SORT ORDER BY STOPKEY| | 14 |
| 4 | TABLE ACCESS FULL | EMP | 14 |
------------------------------------------------
SQL> select empno, ename, hiredate
2 from emp
3 order by hiredate desc
4 fetch first 5 rows only;
167
-------------------------------------------------
| Id | Operation | Name | Rows |
-------------------------------------------------
| 0 | SELECT STATEMENT | | 14 |
|* 1 | VIEW | | 14 |
|* 2 | WINDOW SORT PUSHED RANK| | 14 |
| 3 | TABLE ACCESS FULL | EMP | 14 |
-------------------------------------------------
you get other benefits
168
oc02.sql
169
"but what about the next page ?"
170
forget
the
next
page
new query
171
SQL> select empno, ename, hiredate
2 from emp
3 order by hiredate desc
4 offset 5 rows fetch first 5 rows only;
EMPNO ENAME HIREDATE
---------- ---------- ---------
7839 KING 17-NOV-81
7654 MARTIN 28-SEP-81
7844 TURNER 08-SEP-81
7782 CLARK 09-JUN-81
7698 BLAKE 01-MAY-81
172
forget the OFFSET clause
173
SQL> select empno, ename, hiredate
2 from emp
3 order by hiredate desc;
HIREDATE EMPNO ENAME
--------- ---------- --------
12-JAN-83 7876 ADAMS
09-DEC-82 7788 SCOTT
23-JAN-82 7934 MILLER
03-DEC-81 7902 FORD
03-DEC-81 7900 JAMES
17-NOV-81 7839 KING
28-SEP-81 7654 MARTIN
08-SEP-81 7844 TURNER
09-JUN-81 7782 CLARK
01-MAY-81 7698 BLAKE
02-APR-81 7566 JONES
22-FEB-81 7521 WARD
20-FEB-81 7499 ALLEN
17-DEC-80 7369 SMITH
174
fetch first 5 rows
offset 5 fetch next ...
17-FEB-91 7521 BROWN
SQL> select empno, ename, hiredate
2 from emp
3 order by hiredate desc;
HIREDATE EMPNO ENAME
--------- ---------- --------
12-JAN-83 7876 ADAMS
09-DEC-82 7788 SCOTT
23-JAN-82 7934 MILLER
03-DEC-81 7902 FORD
03-DEC-81 7900 JAMES
17-NOV-81 7839 KING
28-SEP-81 7654 MARTIN
08-SEP-81 7844 TURNER
09-JUN-81 7782 CLARK
01-MAY-81 7698 BLAKE
02-APR-81 7566 JONES
22-FEB-81 7521 WARD
20-FEB-81 7499 ALLEN
17-DEC-80 7369 SMITH
175
17-FEB-91 7521 BROWN
SQL> select empno, ename, hiredate
2 from emp
3 where hiredate < :last_shown
3 order by hiredate desc;
176
"an expensive query per page ?!?!
consider result caching
177
SQL> with first_200 as
2 ( select f.*, rownum r
3 from
4 ( select *
5 from t
6 order by owner, object_name desc
7 ) f
8 where rownum <= 200
9 )
10 select *
11 from first_200
12 where r <= 10
178
/*+ result_cache */ rownum r, f.*
oc03.sql
r between 11 and 20
179
8
we all know about analytics
180
SQL> select row_number() OVER ( order by sal )
2 from emp
3 ...
181
https://bit.ly/analytic_sql
182
“Show me lowest salary for each department...”
SQL> select deptno, min(sal)
2 from emp
3 group by deptno;
“...and I need to know who has that
lowest salary as well”
SQL> select deptno, empno, min(sal)
2 from emp
3 group by deptno;
ORA-00979: not a GROUP BY expression
KEEP extension
183
SQL> select deptno, min(sal), min(empno)
2 KEEP ( dense_rank FIRST order by sal) empno
3 from emp
4 group by deptno
5 /
DEPTNO MIN(SAL) EMPNO
---------- ---------- ----------
10 1300 7934
20 800 7369
30 950 7900
Emp 7934 has the
lowest salary in dept 10
184
185
nearly
done!
pattern matching
186
187
188
189
AML
190
anti money laundering
"Find 10 consecutive deposits in a
24 hour period, then
a withdrawal within three days of
the last deposit, at a different retail outlet"
191
ACCT TSTAMP TYP AMT LOC
---------- ------------------ ---------- ------- ----
54261 25/01/19 17:20:55 Deposit 100 Perth
54261 25/01/19 17:56:58 Deposit 165 Perth
54261 26/01/19 11:24:14 Deposit 30 Subiaco
54261 26/01/19 11:47:53 Deposit 45 Guildford
54261 26/01/19 12:59:38 Deposit 100 Claremont
54261 26/01/19 13:26:04 Deposit 80 Perth
54261 26/01/19 14:41:09 Deposit 50 Perth
54261 26/01/19 14:53:12 Deposit 50 Nedlands
54261 26/01/19 15:15:05 Deposit 50 Leederville
54261 26/01/19 15:51:17 Deposit 50 Guildford
54261 26/01/19 16:15:02 Deposit 120 Perth
54261 26/01/19 16:36:51 Deposit 100 Perth
54261 26/01/19 16:55:09 Deposit 100 Perth
54261 26/01/19 18:07:17 Withdrawal -500 Nedlands
192
hard ...
193
pattern matching
194
SQL> select acct, tstamp, wthd_tstamp, txn_type, amt
2 from account_txns
3 MATCH_RECOGNIZE
4 ( partition by acct
5 order by tstamp
6 measures
7 dep.tstamp dep_tstamp,
8 wthd.tstamp wthd_tstamp
9 all rows per match
10 pattern ( dep{10,} wthd )
11 define
12 dep as
13 txn_type = 'Deposit',
14 wthd as
15 txn_type = 'Withdrawal'
16 and last(dep.tstamp)-first(dep.tstamp) < interval '1' day
17 and wthd.tstamp - last(dep.tstamp) < interval '3' day
18 and wthd.location != last(dep.location)
19 ) 195
196
https://tinyurl.com/pattern-match
197
last
198
199
"talking" to your database
... makes it faster
200
example
201
STORES
CUSTOMERS
SALES
select prod_id, max(amount)
from stores st,
customers c,
sales s
where s.cust_id = c.cust_id(+)
and c.store_id = st.store_id
and s.amount > 10
group by prod_id
202
hash outer join ? nested loop ?
STORES first ?
sort merge ?
---------------------------------------------------
| Id | Operation | Name | Rows |
---------------------------------------------------
| 0 | SELECT STATEMENT | | 100 |
| 1 | HASH GROUP BY | | 100 |
|* 2 | HASH JOIN | | 990K |
| 3 | NESTED LOOPS SEMI | | 5000 |
| 4 | TABLE ACCESS FULL| CUSTOMERS | 5000 |
|* 5 | INDEX UNIQUE SCAN| STORE_IX | 50 |
|* 6 | TABLE ACCESS FULL | SALES | 990K |
---------------------------------------------------
203
204
can we do better ?
add indexes ?
rewrite query ?
result cache ?
materialized view ?
205
share your knowledge with the db
oc04.sql
wrap up
206
SQL
207
very cool
208
very powerful
209
less code
210
never too early to start
211
Copyright © 2018, Oracle and/or its affiliates. All rights reserved. |
That's a wrap!
youtube bit.ly/youtube-connor
blog bit.ly/blog-connor
twitter bit.ly/twitter-connor

More Related Content

What's hot

UKOUG 2019 - SQL features
UKOUG 2019 - SQL featuresUKOUG 2019 - SQL features
UKOUG 2019 - SQL featuresConnor McDonald
 
Pattern Matching with SQL - APEX World Rotterdam 2019
Pattern Matching with SQL - APEX World Rotterdam 2019Pattern Matching with SQL - APEX World Rotterdam 2019
Pattern Matching with SQL - APEX World Rotterdam 2019Connor McDonald
 
Latin America Tour 2019 - pattern matching
Latin America Tour 2019 - pattern matchingLatin America Tour 2019 - pattern matching
Latin America Tour 2019 - pattern matchingConnor McDonald
 
SQL techniques for faster applications
SQL techniques for faster applicationsSQL techniques for faster applications
SQL techniques for faster applicationsConnor McDonald
 
UKOUG - 25 years of hints and tips
UKOUG - 25 years of hints and tipsUKOUG - 25 years of hints and tips
UKOUG - 25 years of hints and tipsConnor McDonald
 
Perth APAC Groundbreakers tour - SQL Techniques
Perth APAC Groundbreakers tour - SQL TechniquesPerth APAC Groundbreakers tour - SQL Techniques
Perth APAC Groundbreakers tour - SQL TechniquesConnor McDonald
 
Latin America tour 2019 - Flashback
Latin America tour 2019 -  FlashbackLatin America tour 2019 -  Flashback
Latin America tour 2019 - FlashbackConnor McDonald
 
Agile Database Development with JSON
Agile Database Development with JSONAgile Database Development with JSON
Agile Database Development with JSONChris Saxon
 
The Five Best Things To Happen To SQL
The Five Best Things To Happen To SQLThe Five Best Things To Happen To SQL
The Five Best Things To Happen To SQLConnor McDonald
 
Demystifying cost based optimization
Demystifying cost based optimizationDemystifying cost based optimization
Demystifying cost based optimizationRiyaj Shamsudeen
 
Get your moneys worth out of your database
Get your moneys worth out of your databaseGet your moneys worth out of your database
Get your moneys worth out of your databasePatrick Barel
 
Oracle Database 12c Application Development
Oracle Database 12c Application DevelopmentOracle Database 12c Application Development
Oracle Database 12c Application DevelopmentSaurabh K. Gupta
 
Extreme JavaScript Performance
Extreme JavaScript PerformanceExtreme JavaScript Performance
Extreme JavaScript PerformanceThomas Fuchs
 
Down the rabbit hole, profiling in Django
Down the rabbit hole, profiling in DjangoDown the rabbit hole, profiling in Django
Down the rabbit hole, profiling in DjangoRemco Wendt
 
JPoint 2016 - Валеев Тагир - Странности Stream API
JPoint 2016 - Валеев Тагир - Странности Stream APIJPoint 2016 - Валеев Тагир - Странности Stream API
JPoint 2016 - Валеев Тагир - Странности Stream APItvaleev
 
Using Optimizer Hints to Improve MySQL Query Performance
Using Optimizer Hints to Improve MySQL Query PerformanceUsing Optimizer Hints to Improve MySQL Query Performance
Using Optimizer Hints to Improve MySQL Query Performanceoysteing
 
Rich and Snappy Apps (No Scaling Required)
Rich and Snappy Apps (No Scaling Required)Rich and Snappy Apps (No Scaling Required)
Rich and Snappy Apps (No Scaling Required)Thomas Fuchs
 

What's hot (20)

UKOUG 2019 - SQL features
UKOUG 2019 - SQL featuresUKOUG 2019 - SQL features
UKOUG 2019 - SQL features
 
Pattern Matching with SQL - APEX World Rotterdam 2019
Pattern Matching with SQL - APEX World Rotterdam 2019Pattern Matching with SQL - APEX World Rotterdam 2019
Pattern Matching with SQL - APEX World Rotterdam 2019
 
Latin America Tour 2019 - pattern matching
Latin America Tour 2019 - pattern matchingLatin America Tour 2019 - pattern matching
Latin America Tour 2019 - pattern matching
 
SQL techniques for faster applications
SQL techniques for faster applicationsSQL techniques for faster applications
SQL techniques for faster applications
 
UKOUG - 25 years of hints and tips
UKOUG - 25 years of hints and tipsUKOUG - 25 years of hints and tips
UKOUG - 25 years of hints and tips
 
Perth APAC Groundbreakers tour - SQL Techniques
Perth APAC Groundbreakers tour - SQL TechniquesPerth APAC Groundbreakers tour - SQL Techniques
Perth APAC Groundbreakers tour - SQL Techniques
 
ANSI vs Oracle language
ANSI vs Oracle languageANSI vs Oracle language
ANSI vs Oracle language
 
Flashback ITOUG
Flashback ITOUGFlashback ITOUG
Flashback ITOUG
 
Latin America tour 2019 - Flashback
Latin America tour 2019 -  FlashbackLatin America tour 2019 -  Flashback
Latin America tour 2019 - Flashback
 
Agile Database Development with JSON
Agile Database Development with JSONAgile Database Development with JSON
Agile Database Development with JSON
 
The Five Best Things To Happen To SQL
The Five Best Things To Happen To SQLThe Five Best Things To Happen To SQL
The Five Best Things To Happen To SQL
 
実践 memcached
実践 memcached実践 memcached
実践 memcached
 
Demystifying cost based optimization
Demystifying cost based optimizationDemystifying cost based optimization
Demystifying cost based optimization
 
Get your moneys worth out of your database
Get your moneys worth out of your databaseGet your moneys worth out of your database
Get your moneys worth out of your database
 
Oracle Database 12c Application Development
Oracle Database 12c Application DevelopmentOracle Database 12c Application Development
Oracle Database 12c Application Development
 
Extreme JavaScript Performance
Extreme JavaScript PerformanceExtreme JavaScript Performance
Extreme JavaScript Performance
 
Down the rabbit hole, profiling in Django
Down the rabbit hole, profiling in DjangoDown the rabbit hole, profiling in Django
Down the rabbit hole, profiling in Django
 
JPoint 2016 - Валеев Тагир - Странности Stream API
JPoint 2016 - Валеев Тагир - Странности Stream APIJPoint 2016 - Валеев Тагир - Странности Stream API
JPoint 2016 - Валеев Тагир - Странности Stream API
 
Using Optimizer Hints to Improve MySQL Query Performance
Using Optimizer Hints to Improve MySQL Query PerformanceUsing Optimizer Hints to Improve MySQL Query Performance
Using Optimizer Hints to Improve MySQL Query Performance
 
Rich and Snappy Apps (No Scaling Required)
Rich and Snappy Apps (No Scaling Required)Rich and Snappy Apps (No Scaling Required)
Rich and Snappy Apps (No Scaling Required)
 

Similar to KScope19 - SQL Features

ILOUG 2019 - SQL features for Developers
ILOUG 2019 - SQL features for DevelopersILOUG 2019 - SQL features for Developers
ILOUG 2019 - SQL features for DevelopersConnor McDonald
 
Wellington APAC Groundbreakers tour - SQL Pattern Matching
Wellington APAC Groundbreakers tour - SQL Pattern MatchingWellington APAC Groundbreakers tour - SQL Pattern Matching
Wellington APAC Groundbreakers tour - SQL Pattern MatchingConnor McDonald
 
SQL techniques for faster applications
SQL techniques for faster applicationsSQL techniques for faster applications
SQL techniques for faster applicationsConnor McDonald
 
OOW19 - Ten Amazing SQL features
OOW19 - Ten Amazing SQL featuresOOW19 - Ten Amazing SQL features
OOW19 - Ten Amazing SQL featuresConnor McDonald
 
Oren nakdimon oh really... i didn't know it is supported in standard edition
Oren nakdimon   oh really... i didn't know it is supported in standard editionOren nakdimon   oh really... i didn't know it is supported in standard edition
Oren nakdimon oh really... i didn't know it is supported in standard editionOren Nakdimon
 
C-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression CalculatorC-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression CalculatorNeeraj Kaushik
 
How to tune a query - ODTUG 2012
How to tune a query - ODTUG 2012How to tune a query - ODTUG 2012
How to tune a query - ODTUG 2012Connor McDonald
 
Wellington APAC Groundbreakers tour - Upgrading to the 12c Optimizer
Wellington APAC Groundbreakers tour - Upgrading to the 12c OptimizerWellington APAC Groundbreakers tour - Upgrading to the 12c Optimizer
Wellington APAC Groundbreakers tour - Upgrading to the 12c OptimizerConnor McDonald
 
Analytic functions in Oracle SQL - BIWA 2017
Analytic functions in Oracle SQL - BIWA 2017Analytic functions in Oracle SQL - BIWA 2017
Analytic functions in Oracle SQL - BIWA 2017Connor McDonald
 
#dbhouseparty - Real World Problem Solving with SQL
#dbhouseparty - Real World Problem Solving with SQL#dbhouseparty - Real World Problem Solving with SQL
#dbhouseparty - Real World Problem Solving with SQLTammy Bednar
 
OpenWorld 2018 - Common Application Developer Disasters
OpenWorld 2018 - Common Application Developer DisastersOpenWorld 2018 - Common Application Developer Disasters
OpenWorld 2018 - Common Application Developer DisastersConnor McDonald
 
80 different SQL Queries with output
80 different SQL Queries with output80 different SQL Queries with output
80 different SQL Queries with outputNexus
 

Similar to KScope19 - SQL Features (20)

ILOUG 2019 - SQL features for Developers
ILOUG 2019 - SQL features for DevelopersILOUG 2019 - SQL features for Developers
ILOUG 2019 - SQL features for Developers
 
Wellington APAC Groundbreakers tour - SQL Pattern Matching
Wellington APAC Groundbreakers tour - SQL Pattern MatchingWellington APAC Groundbreakers tour - SQL Pattern Matching
Wellington APAC Groundbreakers tour - SQL Pattern Matching
 
SQL techniques for faster applications
SQL techniques for faster applicationsSQL techniques for faster applications
SQL techniques for faster applications
 
OOW19 - Ten Amazing SQL features
OOW19 - Ten Amazing SQL featuresOOW19 - Ten Amazing SQL features
OOW19 - Ten Amazing SQL features
 
ORACLE NOTES
ORACLE NOTESORACLE NOTES
ORACLE NOTES
 
Oren nakdimon oh really... i didn't know it is supported in standard edition
Oren nakdimon   oh really... i didn't know it is supported in standard editionOren nakdimon   oh really... i didn't know it is supported in standard edition
Oren nakdimon oh really... i didn't know it is supported in standard edition
 
C-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression CalculatorC-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression Calculator
 
How to tune a query - ODTUG 2012
How to tune a query - ODTUG 2012How to tune a query - ODTUG 2012
How to tune a query - ODTUG 2012
 
Wellington APAC Groundbreakers tour - Upgrading to the 12c Optimizer
Wellington APAC Groundbreakers tour - Upgrading to the 12c OptimizerWellington APAC Groundbreakers tour - Upgrading to the 12c Optimizer
Wellington APAC Groundbreakers tour - Upgrading to the 12c Optimizer
 
Analytic functions in Oracle SQL - BIWA 2017
Analytic functions in Oracle SQL - BIWA 2017Analytic functions in Oracle SQL - BIWA 2017
Analytic functions in Oracle SQL - BIWA 2017
 
#dbhouseparty - Real World Problem Solving with SQL
#dbhouseparty - Real World Problem Solving with SQL#dbhouseparty - Real World Problem Solving with SQL
#dbhouseparty - Real World Problem Solving with SQL
 
OpenWorld 2018 - Common Application Developer Disasters
OpenWorld 2018 - Common Application Developer DisastersOpenWorld 2018 - Common Application Developer Disasters
OpenWorld 2018 - Common Application Developer Disasters
 
SQL.pptx
SQL.pptxSQL.pptx
SQL.pptx
 
Learning Dtrace
Learning DtraceLearning Dtrace
Learning Dtrace
 
80 different SQL Queries with output
80 different SQL Queries with output80 different SQL Queries with output
80 different SQL Queries with output
 
Cube rollup slides
Cube rollup slidesCube rollup slides
Cube rollup slides
 
Chapter 1
Chapter 1Chapter 1
Chapter 1
 
Vcs16
Vcs16Vcs16
Vcs16
 
Oracle
OracleOracle
Oracle
 
Analytic SQL Sep 2013
Analytic SQL Sep 2013Analytic SQL Sep 2013
Analytic SQL Sep 2013
 

More from Connor McDonald

APEX tour 2019 - successful development with autonomous
APEX tour 2019 - successful development with autonomousAPEX tour 2019 - successful development with autonomous
APEX tour 2019 - successful development with autonomousConnor McDonald
 
APAC Groundbreakers 2019 - Perth/Melbourne
APAC Groundbreakers 2019 - Perth/Melbourne APAC Groundbreakers 2019 - Perth/Melbourne
APAC Groundbreakers 2019 - Perth/Melbourne Connor McDonald
 
OOW19 - Flashback, not just for DBAs
OOW19 - Flashback, not just for DBAsOOW19 - Flashback, not just for DBAs
OOW19 - Flashback, not just for DBAsConnor McDonald
 
OOW19 - Read consistency
OOW19 - Read consistencyOOW19 - Read consistency
OOW19 - Read consistencyConnor McDonald
 
OOW19 - Slower and less secure applications
OOW19 - Slower and less secure applicationsOOW19 - Slower and less secure applications
OOW19 - Slower and less secure applicationsConnor McDonald
 
OOW19 - Killing database sessions
OOW19 - Killing database sessionsOOW19 - Killing database sessions
OOW19 - Killing database sessionsConnor McDonald
 
Latin America Tour 2019 - 18c and 19c featues
Latin America Tour 2019   - 18c and 19c featuesLatin America Tour 2019   - 18c and 19c featues
Latin America Tour 2019 - 18c and 19c featuesConnor McDonald
 
Latin America Tour 2019 - slow data and sql processing
Latin America Tour 2019  - slow data and sql processingLatin America Tour 2019  - slow data and sql processing
Latin America Tour 2019 - slow data and sql processingConnor McDonald
 
OG Yatra - upgrading to the new 12c+ optimizer
OG Yatra - upgrading to the new 12c+ optimizerOG Yatra - upgrading to the new 12c+ optimizer
OG Yatra - upgrading to the new 12c+ optimizerConnor McDonald
 
OG Yatra - 25 years of hints and tips
OG Yatra - 25 years of hints and tipsOG Yatra - 25 years of hints and tips
OG Yatra - 25 years of hints and tipsConnor McDonald
 
OG Yatra - Flashback, not just for developers
OG Yatra - Flashback, not just for developersOG Yatra - Flashback, not just for developers
OG Yatra - Flashback, not just for developersConnor McDonald
 
Kscope19 - Flashback: Good for Developers as well as DBAs
Kscope19 - Flashback: Good for Developers as well as DBAsKscope19 - Flashback: Good for Developers as well as DBAs
Kscope19 - Flashback: Good for Developers as well as DBAsConnor McDonald
 
Kscope19 - Understanding the basics of SQL processing
Kscope19 - Understanding the basics of SQL processingKscope19 - Understanding the basics of SQL processing
Kscope19 - Understanding the basics of SQL processingConnor McDonald
 
18c and 19c features for DBAs
18c and 19c features for DBAs18c and 19c features for DBAs
18c and 19c features for DBAsConnor McDonald
 
APEX Connect 2019 - SQL Tuning 101
APEX Connect 2019 - SQL Tuning 101APEX Connect 2019 - SQL Tuning 101
APEX Connect 2019 - SQL Tuning 101Connor McDonald
 

More from Connor McDonald (15)

APEX tour 2019 - successful development with autonomous
APEX tour 2019 - successful development with autonomousAPEX tour 2019 - successful development with autonomous
APEX tour 2019 - successful development with autonomous
 
APAC Groundbreakers 2019 - Perth/Melbourne
APAC Groundbreakers 2019 - Perth/Melbourne APAC Groundbreakers 2019 - Perth/Melbourne
APAC Groundbreakers 2019 - Perth/Melbourne
 
OOW19 - Flashback, not just for DBAs
OOW19 - Flashback, not just for DBAsOOW19 - Flashback, not just for DBAs
OOW19 - Flashback, not just for DBAs
 
OOW19 - Read consistency
OOW19 - Read consistencyOOW19 - Read consistency
OOW19 - Read consistency
 
OOW19 - Slower and less secure applications
OOW19 - Slower and less secure applicationsOOW19 - Slower and less secure applications
OOW19 - Slower and less secure applications
 
OOW19 - Killing database sessions
OOW19 - Killing database sessionsOOW19 - Killing database sessions
OOW19 - Killing database sessions
 
Latin America Tour 2019 - 18c and 19c featues
Latin America Tour 2019   - 18c and 19c featuesLatin America Tour 2019   - 18c and 19c featues
Latin America Tour 2019 - 18c and 19c featues
 
Latin America Tour 2019 - slow data and sql processing
Latin America Tour 2019  - slow data and sql processingLatin America Tour 2019  - slow data and sql processing
Latin America Tour 2019 - slow data and sql processing
 
OG Yatra - upgrading to the new 12c+ optimizer
OG Yatra - upgrading to the new 12c+ optimizerOG Yatra - upgrading to the new 12c+ optimizer
OG Yatra - upgrading to the new 12c+ optimizer
 
OG Yatra - 25 years of hints and tips
OG Yatra - 25 years of hints and tipsOG Yatra - 25 years of hints and tips
OG Yatra - 25 years of hints and tips
 
OG Yatra - Flashback, not just for developers
OG Yatra - Flashback, not just for developersOG Yatra - Flashback, not just for developers
OG Yatra - Flashback, not just for developers
 
Kscope19 - Flashback: Good for Developers as well as DBAs
Kscope19 - Flashback: Good for Developers as well as DBAsKscope19 - Flashback: Good for Developers as well as DBAs
Kscope19 - Flashback: Good for Developers as well as DBAs
 
Kscope19 - Understanding the basics of SQL processing
Kscope19 - Understanding the basics of SQL processingKscope19 - Understanding the basics of SQL processing
Kscope19 - Understanding the basics of SQL processing
 
18c and 19c features for DBAs
18c and 19c features for DBAs18c and 19c features for DBAs
18c and 19c features for DBAs
 
APEX Connect 2019 - SQL Tuning 101
APEX Connect 2019 - SQL Tuning 101APEX Connect 2019 - SQL Tuning 101
APEX Connect 2019 - SQL Tuning 101
 

Recently uploaded

Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraDeakin University
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxnull - The Open Security Community
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 

Recently uploaded (20)

Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning era
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
The transition to renewables in India.pdf
The transition to renewables in India.pdfThe transition to renewables in India.pdf
The transition to renewables in India.pdf
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 

KScope19 - SQL Features

  • 1.
  • 2. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. SQLThe meanest, fastest thing out there Connor McDonald 2
  • 3. Copyright © 2018, Oracle and/or its affiliates. All rights reserved. Connor McDonald
  • 4. Copyright © 2018, Oracle and/or its affiliates. All rights reserved. |Copyright © 2018, Oracle and/or its affiliates. All rights reserved. | 4
  • 5. Copyright © 2018, Oracle and/or its affiliates. All rights reserved. |Copyright © 2018, Oracle and/or its affiliates. All rights reserved. | 5
  • 6. Copyright © 2018, Oracle and/or its affiliates. All rights reserved. | Stuff youtube bit.ly/youtube-connor blog bit.ly/blog-connor twitter bit.ly/twitter-connor 400+ posts mainly on database & development 250 technical videos, new uploads every week rants and raves on tech and the world :-)
  • 7. Copyright © 2018, Oracle and/or its affiliates. All rights reserved. etc... facebook bit.ly/facebook-connor linkedin bit.ly/linkedin-connor instagram bit.ly/instagram-connor slideshare bit.ly/slideshare-connor
  • 8. Copyright © 2018, Oracle and/or its affiliates. All rights reserved. |Copyright © 2018, Oracle and/or its affiliates. All rights reserved. | https://asktom.oracle.com
  • 9. 9
  • 10. SO
  • 11. THE
  • 12. BIG
  • 14. IS
  • 16. why talk about SQL ? 16
  • 18. 18
  • 19. why talk about SQL # 1 19
  • 21. 21
  • 22. why talk about SQL # 2 22
  • 26. 26 "fine-grained to perform a single function" "Each service is ... minimal, and complete" https://en.wikipedia.org/wiki/Microservices select COUNT(*) from PEOPLE where GENDER = 'MALE'
  • 29. SQL is entirely APIs ! 29
  • 30. 30 "By abstracting the underlying implementation" "describes the expected behaviour ... but can have multiple implementations" https://en.wikipedia.org/wiki/Application_programming_interface select NAME, STREET_NO, ZIP_CODE from PEOPLE p, ADDRESS a where p.AGE > 50 and p.ADDRESS_ID = a.ADDRESS_ID;
  • 31. why talk about SQL # 3 31
  • 34. ... yet we end up data processing :-( 34
  • 35. 35
  • 37. this session is not about ... 37
  • 39. we can do anything ... 39
  • 40. SQL> with x( s, ind ) as 2 ( select sud, instr( sud, '.' ) 3 from ( select replace(replace( 4 replace(replace(:board,'-'),'|'),' '),chr(10)) sud 5 from dual ) 6 union all 7 select substr(s,1,ind-1)||z||substr(s,ind+1) 8 , instr(s,'.',ind+1) 9 from x 10 , ( select to_char( rownum ) z 11 from dual connect by rownum <= 9 ) z 12 where ind > 0 13 and not exists ( 14 select null 15 from ( select rownum lp from dual 16 connect by rownum <= 9 ) 17 where z = substr(s,trunc((ind-1)/9)*9+lp,1) 40
  • 41. 18 or z = substr(s,mod(ind-1,9)-8+lp*9,1) 19 or z = substr(s,mod(trunc((ind-1)/3),3)*3 20 +trunc((ind-1)/27)*27+lp 21 +trunc((lp-1)/3)*6,1) 22 ) 23 ), 24 result as ( 25 select s 26 from x 27 where ind = 0 ) 28 select 29 regexp_replace(substr(s,(idx-1)*9+1,9), 30 '(...)(...)(...)', 31 '1|2|3')|| 32 case when mod(idx,3)=0 then chr(10)||rpad('-',11,'-') end soln 33 from result, 34 ( select level idx 35 from dual 36 connect by level <= 9 ) 41 Ack: Anton Scheffer, https://technology.amis.nl
  • 42. SQL> variable board varchar2(1000) SQL> begin :board := 2 '53.|.7.|... 3 6..|195|... 4 .98|...|.6. 5 ----------- 6 8..|.61|..3 7 4..|8.3|..1 8 7..|.2.|..6 9 ----------- 10 .6.|...|28. 11 ...|419|..5 12 ...|.8.|.79 13 '; 14 end; 42 5 3 7 6 1 9 5 9 8 6 8 6 1 3 4 8 3 1 7 2 6 6 2 8 4 1 9 5 8 7 9
  • 44. 44 100% % of developers that will need to solve Sudoku as part of their job
  • 45. 45 100% % of developers that need to get real stuff done
  • 47. 47 1
  • 50.
  • 53. DBA friendship is important 53 oc00.sql
  • 54. 54 2
  • 56. "Employee salary list, plus department total, plus grand total" 56
  • 57. 57
  • 58. SQL> select empno, ename, sal, deptno from emp 2 order by deptno; EMPNO ENAME SAL DEPTNO ---------- ---------- ---------- ---------- 7782 CLARK 2450 10 7839 KING 5000 10 7934 MILLER 1300 10 ... 7900 JAMES 950 30 7698 BLAKE 2850 30 7654 MARTIN 1250 30 58 SQL> select deptno, 2 sum(sal) 3 from emp 4 group by deptno 5 order by deptno; DEPTNO SUM(SAL) ---------- ---------- 10 8750 20 10875 30 9400 SQL> select sum(sal) from emp; SUM(SAL) ---------- 29025
  • 59. from 3 to 2 59 rollup
  • 60. SQL> select empno, ename, sal, deptno from emp 2 order by deptno; EMPNO ENAME SAL DEPTNO ---------- ---------- ---------- ---------- 7782 CLARK 2450 10 7839 KING 5000 10 7934 MILLER 1300 10 ... 7900 JAMES 950 30 7698 BLAKE 2850 30 7654 MARTIN 1250 30 60 SQL> select deptno, 2 sum(sal) 3 from emp 4 group by rollup(deptno) 5 order by deptno; DEPTNO SUM(SAL) ---------- ---------- 10 8750 20 10875 30 9400 29025
  • 62. EMPNO SAL DEPTNO ---------- ---------- ---------- 7782 2450 10 7839 5000 10 7934 1300 10 7566 2975 20 7902 3000 20 7876 1100 20 7369 800 20 62 DEPTNO SUM(SAL) ---------- ---------- 10 8750 20 10875 30 9400 29025 7782 2450 10 7839 5000 10 7934 1300 10 7566 2975 20 10 8750
  • 63. from 2 to 1 63
  • 64. SQL> select deptno, 2 nvl2(rownum,max(empno),null) empno, 3 nvl2(rownum,max(ename),null) ename, 4 sum(sal) 5 from emp 6 group by rollup(deptno,rownum) 7 order by deptno,empno; DEPTNO EMPNO ENAME SUM(SAL) ---------- ---------- ---------- ---------- 10 7782 CLARK 2450 10 7839 KING 5000 10 7934 MILLER 1300 10 8750 20 7369 SMITH 800 20 7566 JONES 2975 ... 30 7900 JAMES 950 30 9400 2902564
  • 65. all totals are possible 65
  • 66. SQL> select deptno,job,sum(sal) from scott.emp 2 group by CUBE(deptno,job) 3 order by deptno,job; DEPTNO JOB SUM(SAL) ---------- --------- ---------- 10 CLERK 1300 10 MANAGER 2450 10 PRESIDENT 5000 10 8750 20 ANALYST 6000 20 CLERK 1900 20 MANAGER 2975 20 10875 30 CLERK 950 30 MANAGER 2850 30 SALESMAN 5600 30 9400 ANALYST 6000 CLERK 4150 MANAGER 8275 PRESIDENT 5000 SALESMAN 5600 29025 66
  • 68. SQL> select deptno, job, mgr, sum(sal) from emp 2 group by grouping sets ( 3 (deptno), 4 (job,mgr), () ) ; DEPTNO JOB MGR SUM(SAL) ---------- --------- ---------- ---------- CLERK 7902 800 PRESIDENT 5000 CLERK 7698 950 CLERK 7788 1100 CLERK 7782 1300 SALESMAN 7698 5600 MANAGER 7839 8275 ANALYST 7566 6000 10 8750 20 10875 30 9400 29025 68
  • 69. 69 3
  • 71. C#, C++ ESB Tuxedo Weblogic Stored Procedure 71
  • 72. for (int i = 0; i < WinningCombinations.Count; ++i) { if (WinningCombinations[i].Investment > 0 && WinningCombinations[i].PrimaryDividend > MinDividendDeadHeat) { maxDivisor = Math.Max(maxDivisor, WinningCombinations[i].Divisor); } } for (int i = 0; i < WinningCombinations.Count; ++i) { if (WinningCombinations[i].Investment > 0 && WinningCombinations[i].PrimaryDividend > MinDividendDeadHeat) { WinningCombinations[i].Divisor = maxDivisor / WinningCombinations[i].Divisor; sumNewDivisors += WinningCombinations[i].Divisor; } }72
  • 74. 74
  • 77. SQL can be complex 77
  • 78. SQL should "self document" 78
  • 79. query blocks = self documenting SQL 79
  • 80. select emp.* from emp, ( select trunc(hiredate,'YYYY'), max(empno) empno from emp where empno > 0 group by trunc(hiredate,'YYYY') ) x, ( select deptno, avg(sal) from emp group by deptno ) y where x.empno = emp.empno and y.deptno = emp.deptno 80
  • 81. Id | Operation | Name | ----------------------------------------------| 0 | SELECT STATEMENT | | 1 | HASH JOIN | | 2 | TABLE ACCESS BY INDEX ROWID | EMP | 3 | NESTED LOOPS | | 4 | VIEW | | 5 | SORT GROUP BY | | 6 | TABLE ACCESS BY INDEX ROWID| EMP | 7 | INDEX FULL SCAN | E2 | 8 | INDEX RANGE SCAN | E1 | 9 | VIEW | | 10 | SORT GROUP BY | | 11 | TABLE ACCESS BY INDEX ROWID | EMP | 12 | INDEX RANGE SCAN | E2 | 81
  • 82. ? 82 select emp.* from emp, ( select trunc(hiredate,'YYYY'), max(empno) empno from emp where empno > 0 group by trunc(hiredate,'YYYY') ) x, ( select deptno, avg(sal) from emp group by deptno ) y where x.empno = emp.empno and y.deptno = emp.deptno Id | Operation | Name | ----------------------------------------------| 0 | SELECT STATEMENT | | 1 | HASH JOIN | | 2 | TABLE ACCESS BY INDEX ROWID | EMP | 3 | NESTED LOOPS | | 4 | VIEW | | 5 | SORT GROUP BY | | 6 | TABLE ACCESS BY INDEX ROWID| EMP | 7 | INDEX FULL SCAN | E2 | 8 | INDEX RANGE SCAN | E1 | 9 | VIEW | | 10 | SORT GROUP BY | | 11 | TABLE ACCESS BY INDEX ROWID | EMP | 12 | INDEX RANGE SCAN | E2 |
  • 83. select emp.* from emp, ( select /*+ QB_NAME(YR_HIRE) */ trunc(hiredate,'YYYY'), max(empno) empno from emp where empno > 0 group by trunc(hiredate,'YYYY') ) x, ( select /*+ QB_NAME(AV_SAL) */ deptno, avg(sal) from emp group by deptno ) y where x.empno = emp.empno and y.deptno = emp.deptno 83 select emp.* from emp, ( select /*+ QB_NAME(YR_HIRE) */ trunc(hiredate,'YYYY'), max(empno) empno from emp where empno > 0 group by trunc(hiredate,'YYYY') ) x, ( select /*+ QB_NAME(AV_SAL) */ deptno, avg(sal) from emp group by deptno ) y where x.empno = emp.empno and y.deptno = emp.deptno
  • 84. Id | Operation | Name | Query Block ----------------------------------------------|-------------- 0 | SELECT STATEMENT | | 1 | HASH JOIN | | 2 | TABLE ACCESS BY INDEX ROWID | EMP | 3 | NESTED LOOPS | | 4 | VIEW | | 5 | SORT GROUP BY | | 6 | TABLE ACCESS BY INDEX ROWID| EMP | 7 | INDEX FULL SCAN | E2 | 8 | INDEX RANGE SCAN | E1 | 9 | VIEW | | 10 | SORT GROUP BY | | 11 | TABLE ACCESS BY INDEX ROWID | EMP | 12 | INDEX RANGE SCAN | E2 | SEL$1 SEL$1 AV_SAL AV_SAL AV_SAL AV_SAL SEL$1 YR_HIRE YR_HIRE YR_HIRE YR_HIRE 84
  • 85. 85 4
  • 87. SQL> insert into MY_TABLE 2 select * 3 from MY_HUGE_GREAT_FAT_TABLE; 87 MY_HUGE_GREAT_FAT_TABLE;
  • 88. 88
  • 89. 89
  • 90. 90
  • 91. 91
  • 92. 92
  • 93. SQL> insert into MY_TABLE 2 select * 3 from MY_HUGE_GREAT_FAT_TABLE; Elapsed: 06:12:34.00 93
  • 94. SQL> insert into MY_TABLE 2 select * 3 from MY_HUGE_GREAT_FAT_TABLE; Elapsed: 06:12:34.00 ERROR at line 1: ORA-01847: day of month must be between 1 and last day of month 94
  • 95. 95
  • 96. 96
  • 97. 97 and then we do this :-)
  • 98. SQL> select count(*) from MY_TABLE; COUNT(*) ---------- 0 98
  • 101. skip / bypass bad rows 101
  • 103. SQL> insert into MY_TABLE 2 select * 3 from MY_HUGE_GREAT_FAT_TABLE 4 where "not a duplicate" 5 and "datatypes are ok" 6 and "foreign keys are ok" 7 and "check constraints are ok" 103
  • 106. DBMS_ERRLOG.CREATE_ERROR_LOG ( dml_table_name IN VARCHAR2, err_log_table_name IN VARCHAR2 := NULL, err_log_table_owner IN VARCHAR2 := NULL, ... 106
  • 107. SQL> desc ERR$_EMP Name Null? Type ----------------------------- -------- ---------------- ORA_ERR_NUMBER$ NUMBER ORA_ERR_MESG$ VARCHAR2(2000) ORA_ERR_ROWID$ ROWID ORA_ERR_OPTYP$ VARCHAR2(2) ORA_ERR_TAG$ VARCHAR2(2000) EMPNO VARCHAR2(4000) ENAME VARCHAR2(4000) JOB VARCHAR2(4000) MGR VARCHAR2(4000) HIREDATE VARCHAR2(4000) SAL VARCHAR2(4000) COMM VARCHAR2(4000) DEPTNO VARCHAR2(4000) 107
  • 108. 108
  • 110. add to EMP from NEW_DATA 110
  • 111. SQL> select * from NEW_DATA; EMPNO SAL DEPTNO ---------- ---------- ---------- 1000 5000 20 100X 3550 10 2000 2500 50 7934 4000 20 111 non-numeric no dept 50 duplicate
  • 112. SQL> exec dbms_errlog.create_error_log( 'EMP' ); PL/SQL procedure successfully completed. SQL> insert into EMP (empno,sal,deptno) 2 select empno,sal,deptno 3 from NEW_DATA 4 LOG ERRORS REJECT LIMIT UNLIMITED; 1 row created. 112 50
  • 113. SQL> select ORA_ERR_OPTYP$ op, ORA_ERR_MESG$, EMPNO 2 from ERR$_EMP OP ORA_ERR_MESG$ EMPNO -- ------------------------------------------------------------ ----- I ORA-01722: invalid number 100X I ORA-02291: integrity constraint (SCOTT.FK_DEPTNO) violated 2000 I ORA-00001: unique constraint (SCOTT.PK_EMP) violated 7934 113
  • 114. 114 5
  • 116. 116 SQL> select * 2 from timeslots; HR -- 8 9 10 11 12 13 14 15 16 SQL> select * 2 from bookings; HR ROOM WHO ------- ---------- ------- 8 Room2 PETE 9 Room1 JOHN 11 Room1 MIKE 14 Room2 JILL 15 Room2 JANE 16 Room1 SAM
  • 118. 118 SQL> SELECT hrs.hr, t1.room, t1.who 2 from timeslots hrs 3 left outer join bookings t1 4 on hrs.hr = t1.hr 5 order by 1 HR ROOM WHO ------- ---------- ---------- 8 Room2 PETE 9 Room1 JOHN 10 11 Room1 MIKE 12 13 14 Room2 JILL 15 Room2 JANE 16 Room1 SAM 118
  • 119. bookings by hour per room 119
  • 120. 120 HR ROOM WHO ------- ---------- ---------- 8 Room2 PETE 9 10 11 12 13 14 Room2 JILL 15 Room2 JANE 16 HR ROOM WHO ------- ---------- ---------- 8 9 Room1 JOHN 10 11 Room1 MIKE 12 13 14 15 16 Room1 SAM
  • 121. 121 SQL> select * 2 from timeslots; HR -- 8 9 10 11 12 13 14 15 16 x "Room 1" x "Room 2" ... x "Room n"
  • 123. SQL> SELECT hrs.hr, t1.room, t1.who 2 FROM bookings t1 3 PARTITION BY (t1.room) 4 RIGHT OUTER JOIN timeslots ON (hrs.hr = t1.hr) 5 order by 1,2 HR ROOM WHO --------- ---------- ---------- 8 Room1 9 Room1 JOHN 10 Room1 11 Room1 MIKE 12 Room1 13 Room1 14 Room1 15 Room1 16 Room1 SAM 8 Room2 PETE 9 Room2 10 Room2 11 Room2 12 Room2 13 Room2 14 Room2 JILL 15 Room2 JANE 16 Room2 123
  • 124. 124 6
  • 128. SQL> WITH last_hire AS 2 ( select deptno, max(hiredate) 3 from emp 4 group by deptno 5 ) 6 select * from last_hire; DEPTNO MAX(HIRED ---------- --------- 30 03-DEC-81 20 12-JAN-83 10 23-JAN-82 128
  • 129. "who cares?....... more code, same result" 129
  • 130. WITH last_hire AS ( select deptno, max(hiredate) from emp group by deptno ) select * from last_hire; 130
  • 131. why is it cool ? 131
  • 133. relational is a rigorous model ... 133
  • 134. relational is the dominant model ... 134
  • 135. relational ... can sortta suck 135
  • 138. "data is represented as mathematical n-ary relations, an n-ary relation being a subset of the Cartesian product of n domains." 138
  • 139. 139
  • 142. "First, get the total salary paid by each department, then get the average of these totals, then list those departments above that average" 142 SQL ?
  • 143. "First, get the total salary paid by department... SQL> WITH dept_salaries AS ( 2 SELECT dname, SUM(sal) dept_sal 3 FROM emp e, dept d 4 WHERE e.deptno = d.deptno 5 GROUP BY dname), 143
  • 144. "...then get the average of these totals... 6 avg_sal AS ( SELECT AVG(dept_sal) avsal 7 FROM dept_salaries) 144
  • 145. "...then list those departments above average." 8 SELECT * FROM dept_salaries d, avg_sal a 9 WHERE d.dept_sal > a.avsal 10 ORDER BY d.dname; 145
  • 146. SQL> WITH dept_salaries AS ( 2 SELECT dname, SUM(sal) dept_sal 3 FROM emp e, dept d 4 WHERE e.deptno = d.deptno 5 GROUP BY dname), 6 avg_sal AS ( SELECT AVG(dept_sal) avsal 7 FROM dept_salaries) 8 SELECT * FROM dept_salaries d, avg_sal a 9 WHERE d.dept_sal > a.avsal 10 ORDER BY d.dname; 146
  • 152. 152 SQL> with raw_data as ( 2 select 3 hrs.hr, 4 t1.room, 5 t1.who 6 from bookings t1 7 partition by (t1.room) 8 right outer join hrs 9 on (hrs.hr = t1.hr) 10 order by 11 hr, room 12 ) 13 select 14 json_arrayagg( 15 json_object(key room||to_char(hr) value who ) 16 order by hr ) as meetings 17 from raw_data ; [{"Room1-08":null}, {"Room1-09":"JOHN"}, {"Room1-10":null}, {"Room1-11":"MIKE"}, {"Room1-12":null}, ... ... {"Room2-14":"JILL"}, {"Room2-15":null}, {"Room2-16":"JANE"}]
  • 153. 153 7
  • 155. 155 "employees by hiredate, recent first"
  • 156. SQL> select empno, ename, hiredate 2 from emp 3 where rownum <= 5 4 order by hiredate desc; EMPNO ENAME HIREDATE ---------- ---------- ------------------- 7654 MARTIN 28/09/1981 00:00:00 7566 JONES 02/04/1981 00:00:00 7521 WARD 22/02/1981 00:00:00 7499 ALLEN 20/02/1981 00:00:00 7369 SMITH 17/12/1980 00:00:00 156
  • 158. SQL> select * 2 from ( 3 select empno, ename, hiredate 4 from emp 5 order by hiredate desc 6 ) 7 where rownum <= 5; EMPNO ENAME HIREDATE ---------- ---------- --------- 7876 ADAMS 12-JAN-83 7788 SCOTT 09-DEC-82 7934 MILLER 23-JAN-82 7900 JAMES 03-DEC-81 7902 FORD 03-DEC-81 158
  • 159. SQL> select * 2 from ( 3 select 4 empno, ename, hiredate, 5 row_number() over ( order by hiredate desc) rn 6 from emp 7 ) 8 where rn <= 5; 159
  • 160. SQL> select empno, ename, hiredate 2 from emp 3 order by hiredate desc 4 fetch first 5 rows only; EMPNO ENAME HIREDATE ---------- ---------- --------- 7876 ADAMS 12-JAN-83 7788 SCOTT 09-DEC-82 7934 MILLER 23-JAN-82 7900 JAMES 03-DEC-81 7902 FORD 03-DEC-81 160
  • 161. 161 "TL;DR ... my app can do it"
  • 162. public static void Paging(Connection conn ) throws Exception { PreparedStatement sql_stmt = conn.prepareStatement( "select empno, ename, hiredate from emp order by hiredate desc"); ResultSet rset = sql_stmt.executeQuery(); int i = 0; while( rset.next() ) { ... i = i + 1; if (i > 5) { break; } } rset.close(); } 162
  • 163.
  • 165. let the database know 165
  • 166. SQL> select * 2 from ( 3 select empno, ename, hiredate 4 from emp 5 order by hiredate desc 6 ) 7 where rownum <= 5; 166 ------------------------------------------------ | Id | Operation | Name | Rows | ------------------------------------------------ | 0 | SELECT STATEMENT | | 5 | |* 1 | COUNT STOPKEY | | | | 2 | VIEW | | 14 | |* 3 | SORT ORDER BY STOPKEY| | 14 | | 4 | TABLE ACCESS FULL | EMP | 14 | ------------------------------------------------
  • 167. SQL> select empno, ename, hiredate 2 from emp 3 order by hiredate desc 4 fetch first 5 rows only; 167 ------------------------------------------------- | Id | Operation | Name | Rows | ------------------------------------------------- | 0 | SELECT STATEMENT | | 14 | |* 1 | VIEW | | 14 | |* 2 | WINDOW SORT PUSHED RANK| | 14 | | 3 | TABLE ACCESS FULL | EMP | 14 | -------------------------------------------------
  • 168. you get other benefits 168 oc02.sql
  • 169. 169 "but what about the next page ?"
  • 172. SQL> select empno, ename, hiredate 2 from emp 3 order by hiredate desc 4 offset 5 rows fetch first 5 rows only; EMPNO ENAME HIREDATE ---------- ---------- --------- 7839 KING 17-NOV-81 7654 MARTIN 28-SEP-81 7844 TURNER 08-SEP-81 7782 CLARK 09-JUN-81 7698 BLAKE 01-MAY-81 172
  • 173. forget the OFFSET clause 173
  • 174. SQL> select empno, ename, hiredate 2 from emp 3 order by hiredate desc; HIREDATE EMPNO ENAME --------- ---------- -------- 12-JAN-83 7876 ADAMS 09-DEC-82 7788 SCOTT 23-JAN-82 7934 MILLER 03-DEC-81 7902 FORD 03-DEC-81 7900 JAMES 17-NOV-81 7839 KING 28-SEP-81 7654 MARTIN 08-SEP-81 7844 TURNER 09-JUN-81 7782 CLARK 01-MAY-81 7698 BLAKE 02-APR-81 7566 JONES 22-FEB-81 7521 WARD 20-FEB-81 7499 ALLEN 17-DEC-80 7369 SMITH 174 fetch first 5 rows offset 5 fetch next ... 17-FEB-91 7521 BROWN
  • 175. SQL> select empno, ename, hiredate 2 from emp 3 order by hiredate desc; HIREDATE EMPNO ENAME --------- ---------- -------- 12-JAN-83 7876 ADAMS 09-DEC-82 7788 SCOTT 23-JAN-82 7934 MILLER 03-DEC-81 7902 FORD 03-DEC-81 7900 JAMES 17-NOV-81 7839 KING 28-SEP-81 7654 MARTIN 08-SEP-81 7844 TURNER 09-JUN-81 7782 CLARK 01-MAY-81 7698 BLAKE 02-APR-81 7566 JONES 22-FEB-81 7521 WARD 20-FEB-81 7499 ALLEN 17-DEC-80 7369 SMITH 175 17-FEB-91 7521 BROWN SQL> select empno, ename, hiredate 2 from emp 3 where hiredate < :last_shown 3 order by hiredate desc;
  • 176. 176 "an expensive query per page ?!?!
  • 178. SQL> with first_200 as 2 ( select f.*, rownum r 3 from 4 ( select * 5 from t 6 order by owner, object_name desc 7 ) f 8 where rownum <= 200 9 ) 10 select * 11 from first_200 12 where r <= 10 178 /*+ result_cache */ rownum r, f.* oc03.sql r between 11 and 20
  • 179. 179 8
  • 180. we all know about analytics 180
  • 181. SQL> select row_number() OVER ( order by sal ) 2 from emp 3 ... 181 https://bit.ly/analytic_sql
  • 182. 182 “Show me lowest salary for each department...” SQL> select deptno, min(sal) 2 from emp 3 group by deptno; “...and I need to know who has that lowest salary as well” SQL> select deptno, empno, min(sal) 2 from emp 3 group by deptno; ORA-00979: not a GROUP BY expression
  • 184. SQL> select deptno, min(sal), min(empno) 2 KEEP ( dense_rank FIRST order by sal) empno 3 from emp 4 group by deptno 5 / DEPTNO MIN(SAL) EMPNO ---------- ---------- ---------- 10 1300 7934 20 800 7369 30 950 7900 Emp 7934 has the lowest salary in dept 10 184
  • 187. 187
  • 188. 188
  • 189. 189
  • 191. "Find 10 consecutive deposits in a 24 hour period, then a withdrawal within three days of the last deposit, at a different retail outlet" 191
  • 192. ACCT TSTAMP TYP AMT LOC ---------- ------------------ ---------- ------- ---- 54261 25/01/19 17:20:55 Deposit 100 Perth 54261 25/01/19 17:56:58 Deposit 165 Perth 54261 26/01/19 11:24:14 Deposit 30 Subiaco 54261 26/01/19 11:47:53 Deposit 45 Guildford 54261 26/01/19 12:59:38 Deposit 100 Claremont 54261 26/01/19 13:26:04 Deposit 80 Perth 54261 26/01/19 14:41:09 Deposit 50 Perth 54261 26/01/19 14:53:12 Deposit 50 Nedlands 54261 26/01/19 15:15:05 Deposit 50 Leederville 54261 26/01/19 15:51:17 Deposit 50 Guildford 54261 26/01/19 16:15:02 Deposit 120 Perth 54261 26/01/19 16:36:51 Deposit 100 Perth 54261 26/01/19 16:55:09 Deposit 100 Perth 54261 26/01/19 18:07:17 Withdrawal -500 Nedlands 192
  • 195. SQL> select acct, tstamp, wthd_tstamp, txn_type, amt 2 from account_txns 3 MATCH_RECOGNIZE 4 ( partition by acct 5 order by tstamp 6 measures 7 dep.tstamp dep_tstamp, 8 wthd.tstamp wthd_tstamp 9 all rows per match 10 pattern ( dep{10,} wthd ) 11 define 12 dep as 13 txn_type = 'Deposit', 14 wthd as 15 txn_type = 'Withdrawal' 16 and last(dep.tstamp)-first(dep.tstamp) < interval '1' day 17 and wthd.tstamp - last(dep.tstamp) < interval '3' day 18 and wthd.location != last(dep.location) 19 ) 195
  • 198. 198
  • 199. 199 "talking" to your database ... makes it faster
  • 202. select prod_id, max(amount) from stores st, customers c, sales s where s.cust_id = c.cust_id(+) and c.store_id = st.store_id and s.amount > 10 group by prod_id 202 hash outer join ? nested loop ? STORES first ? sort merge ?
  • 203. --------------------------------------------------- | Id | Operation | Name | Rows | --------------------------------------------------- | 0 | SELECT STATEMENT | | 100 | | 1 | HASH GROUP BY | | 100 | |* 2 | HASH JOIN | | 990K | | 3 | NESTED LOOPS SEMI | | 5000 | | 4 | TABLE ACCESS FULL| CUSTOMERS | 5000 | |* 5 | INDEX UNIQUE SCAN| STORE_IX | 50 | |* 6 | TABLE ACCESS FULL | SALES | 990K | --------------------------------------------------- 203
  • 204. 204 can we do better ? add indexes ? rewrite query ? result cache ? materialized view ?
  • 205. 205 share your knowledge with the db oc04.sql
  • 211. never too early to start 211
  • 212.
  • 213. Copyright © 2018, Oracle and/or its affiliates. All rights reserved. | That's a wrap! youtube bit.ly/youtube-connor blog bit.ly/blog-connor twitter bit.ly/twitter-connor