SlideShare uma empresa Scribd logo
1 de 111
Baixar para ler offline
9/17/2019
1
Copyright © 2019 Oracle and/or its affiliates.
2
Connor McDonald
1
2
9/17/2019
2
3 3
4 4
3
4
9/17/2019
3
5 5
6
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 :-)
5
6
9/17/2019
4
7
etc...
facebook bit.ly/facebook-connor
linkedin bit.ly/linkedin-connor
instagram bit.ly/instagram-connor
slideshare bit.ly/slideshare-connor
8 8https://asktom.oracle.com
7
8
9/17/2019
5
11
SO
11
12
9/17/2019
6
THE
BIG
13
14
9/17/2019
7
QUESTION
IS
15
16
9/17/2019
8
17
WHY ?
18
why talk about SQL ?
17
18
9/17/2019
9
19
it is old !
20
19
20
9/17/2019
10
21
why talk about SQL # 1
22
NoSQL
non relational
21
22
9/17/2019
11
23
24
why talk about SQL # 2
23
24
9/17/2019
12
25
developers love cool stuff
26
MICROSERVICES
25
26
9/17/2019
13
27
SQL is microservices !
28
"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'
27
28
9/17/2019
14
29
even cooler stuff
30
API
29
30
9/17/2019
15
31
SQL is entirely APIs !
32
"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
32
9/17/2019
16
41
key point
42
this session is not about ...
41
42
9/17/2019
17
43
being a smart-ass
44
we can do anything ...
43
44
9/17/2019
18
45
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)
46
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 )
Ack: Anton Scheffer,
https://technology.amis.nl
45
46
9/17/2019
19
47
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;
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
48
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
-----------
sud.sql
47
48
9/17/2019
20
49
100%
% of developers that
will need to solve Sudoku
as part of their job
50
100%
% of developers that need
to get real work done
49
50
9/17/2019
21
51
real work
52
1
51
52
9/17/2019
22
53
some controversy...
DBA
53
54
9/17/2019
23
55
56
Public
55
56
9/17/2019
24
57
Public
58
DBA friendship is important
oc00.sql
57
58
9/17/2019
25
59
2
60
totals / subtotals
59
60
9/17/2019
26
61
"Employee salary list,
plus department total,
plus grand total"
62
62
61
62
9/17/2019
27
63
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
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
64
from 3 to 2
rollup
63
64
9/17/2019
28
65
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
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
66
still messy...
65
66
9/17/2019
29
67
EMPNO SAL DEPTNO
---------- ---------- ----------
7782 2450 10
7839 5000 10
7934 1300 10
7566 2975 20
7902 3000 20
7876 1100 20
7369 800 20
DEPTNO SUM(SAL)
---------- ----------
10 8750
20 10875
30 9400
29025
7782 2450 10
7839 5000 10
7934 1300 10
7566 2975 20
10 8750
68
from 2 to 1
67
68
9/17/2019
30
69
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
29025
70
all totals are possible
69
70
9/17/2019
31
71
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
72
totally customisable
71
72
9/17/2019
32
73
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
74
3
73
74
9/17/2019
33
75
error logging
76
SQL> insert into MY_TABLE
2 select *
3 from MY_HUGE_GREAT_FAT_TABLE;MY_HUGE_GREAT_FAT_TABLE;
75
76
9/17/2019
34
77
78
77
78
9/17/2019
35
79
80
79
80
9/17/2019
36
81
82
SQL> insert into MY_TABLE
2 select *
3 from MY_HUGE_GREAT_FAT_TABLE;
Elapsed: 06:12:34.00
81
82
9/17/2019
37
83
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
84
84
83
84
9/17/2019
38
85
85
86
and then we do this :-)
85
86
9/17/2019
39
87
SQL> select count(*) from MY_TABLE;
COUNT(*)
----------
0
88
what we would like
87
88
9/17/2019
40
89
keep successful rows
90
skip / bypass bad rows
89
90
9/17/2019
41
91
hard
92
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"
91
92
9/17/2019
42
93
SQL> exec DBMS_ERRLOG.CREATE_ERROR_LOG('EMP')
94
ERR$_EMP
93
94
9/17/2019
43
95
DBMS_ERRLOG.CREATE_ERROR_LOG (
dml_table_name IN VARCHAR2,
err_log_table_name IN VARCHAR2 := NULL,
err_log_table_owner IN VARCHAR2 := NULL,
...
96
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)
95
96
9/17/2019
44
97
97
98
example
97
98
9/17/2019
45
99
add to EMP from NEW_DATA
100
SQL> select * from NEW_DATA;
EMPNO SAL DEPTNO
---------- ---------- ----------
1000 5000 20
100X 3550 10
2000 2500 50
7934 4000 20
non-numeric
no dept 50
duplicate
99
100
9/17/2019
46
101
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.
50
102
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
101
102
9/17/2019
47
103
4
104
partitioned outer join
103
104
9/17/2019
48
105
105
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
106
bookings by hour
conventional outer join
105
106
9/17/2019
49
107
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
108
bookings by hour per room
107
108
9/17/2019
50
109
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
110
SQL> select *
2 from timeslots;
HR
--
8
9
10
11
12
13
14
15
16
x "Room 1"
x "Room 2"
...
x "Room n"
109
110
9/17/2019
51
111
partitioned outer join
112
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
111
112
9/17/2019
52
113
5
114
subquery factoring
113
114
9/17/2019
53
115
common table expressions
116
WITH clause
115
116
9/17/2019
54
117
WITH last_hire AS
(
select deptno, max(hiredate)
from emp
group by deptno
)
select * from last_hire;
118
"who cares?....... more code, same result"
117
118
9/17/2019
55
119
why is it cool ?
120
good solution metaphor
119
120
9/17/2019
56
121
relational is a rigorous model ...
122
relational is the dominant model ...
121
122
9/17/2019
57
123
relational ... can be complicated
124
not our fault
123
124
9/17/2019
58
125
Codd & Date
126
"data is represented as mathematical n-ary
relations, an n-ary relation being a subset of the
Cartesian product of n domains."
125
126
9/17/2019
59
127
?
128
procedural world
127
128
9/17/2019
60
129
step by step
130
"First, get the total salary paid by each department,
then get the average of these totals,
then list those departments above that average"
SQL ?
129
130
9/17/2019
61
131
"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),
132
"...then get the average of these totals...
6 avg_sal AS ( SELECT AVG(dept_sal) avsal
7 FROM dept_salaries)
131
132
9/17/2019
62
133
"...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;
134
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;
133
134
9/17/2019
63
135
programmer's approach....
136
... relational solution
135
136
9/17/2019
64
137
the "finishing touches"
138
everyone loves JSON
137
138
9/17/2019
65
139
recall: partitioned outer join
140
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"}]
139
140
9/17/2019
66
141
6
142
speaking of procedural to relational
141
142
9/17/2019
67
143
scalar queries
144
SQL> select
2 ( select dname
3 from dept
4 where deptno = e.deptno ) dname,
5 decode(empno, 7499,
6 ( select max(sal) from emp ),
7 -1)
8 from
9 ( select * from emp
10 where sal > 0 ) e
11 where
12 ( select max(hiredate) from emp ) < sysdate
13 /
scalar
anywhere an
expression could be
143
144
9/17/2019
68
149
turn procedural into "relational"
150
List all persons in the STAFF table plus their salary calculated
based on CLASS_TYPE column value:
= ‘T’ (temp worker) salary is FIXED_PRICE from
PART_TIME_PACKAGE table
= ‘C’ (contractor) salary is the HRS * HRLY_RATE from
CONTRACT_PACKAGE table
= ‘P’ (permanent) salary is the ANNUAL_SAL + BONUS from
PERM_PACKAGE table
149
150
9/17/2019
69
151
different table per row
152
4 begin
5 for i in ( select * from staff ) loop
6 if i.class_type = 'T' then -- part time
7 select fixed_price
8 into v_sal
9 from part_time_package
10 where id = i.class_id;
11 elsif i.class_type = 'C' then -- contractors
12 select hrs * hrly_rate
13 into v_sal
14 from contract_package
15 where id = i.class_id;
16 elsif i.class_type = 'P' then -- permanent
17 select annual_sal + bonus
18 into v_sal
19 from perm_package
20 where id = i.class_id;
21 end if;
22 dbms_output.put_line(rpad(i.name,20)||lpad(v_sal,10));
23 end loop;
151
152
9/17/2019
70
153
SQL can still do it
154
SQL> select s.name,
2 case class_type
3 when 'T' then (
4 select fixed_price
5 from part_time_package
6 where id = s.class_id )
7 when 'C' then (
8 select hrs * hrly_rate
9 from contract_package
10 where id = s.class_id )
11 when 'P' then (
12 select annual_sal + bonus
13 from perm_package
14 where id = s.class_id )
15 end sal
16 from staff s;
Scalar subquery
NAME SAL
------------------------------ -------
JOHN SMITH 123.45
JOE BLOGGS 2435.54
153
154
9/17/2019
71
155
"big deal..."
156
subquery caching
155
156
9/17/2019
72
157
7
158
transposition
157
158
9/17/2019
73
159
rows to columns, colums to rows
160
"I need sales by product
for each quarter....now"
159
160
9/17/2019
74
161
SQL> select product,
2 trunc(txn_date,'Q') mth,
3 sum(quantity) total
4 from SALES
5 group by product,trunc(txn_date,'Q')
6 order by 1,2;
PRODUCT MTH TOTAL
-------------------- --- ----------
CHAINSAW JAN 251473
CHAINSAW APR 254830
CHAINSAW JUL 251994
CHAINSAW OCT 243748
HAMMER JAN 249889
HAMMER APR 256566
HAMMER JUL 252992
HAMMER OCT 249104
SCREW DRIVER JAN 245988
SCREW DRIVER APR 249219
SCREW DRIVER JUL 252128
SCREW DRIVER OCT 244721
SPADE JAN 242434
SPADE APR 254090
SPADE JUL 259613
...
161
162
9/17/2019
75
163
"That’s wrong!...surely you know
I wanted it ACROSS the page"
163
164
9/17/2019
76
165
pivot clause
166
SQL> select *
2 from (select product,
3 trunc(txn_date,'Q') mth,
4 quantity
5 from sales )
6 pivot( sum(quantity) for mth in
7 ( 'JAN',
8 'APR',
9 'JUL',
10 'OCT') )
11 order by 1
12 /
PRODUCT 'JAN' 'APR' 'JUL' 'OCT'
-------------------- ---------- ---------- ---------- ----------
CHAINSAW 251473 254830 251994 243748
HAMMER 249889 256566 252992 249104
SCREW DRIVER 245988 249219 252128 244721
SPADE 242434 254090 259613 248428
WHEEL BARROW 243899 249327 252296 254137
165
166
9/17/2019
77
167
unpivot as well
173
8
167
173
9/17/2019
78
174
most of us know about analytics
175
SQL> select row_number() OVER ( order by sal )
2 from emp
3 ...
https://bit.ly/analytic_sql
174
175
9/17/2019
79
176
"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"
SQL> select deptno, empno, min(sal)
2 from emp
3 group by deptno;
ORA-00979: not a GROUP BY expression
177
KEEP extension
176
177
9/17/2019
80
178
SQL> select deptno, min(sal),
2 min(empno)
3 KEEP ( dense_rank FIRST order by sal) empno
4 from emp
5 group by deptno;
DEPTNO MIN(SAL) EMPNO
---------- ---------- ----------
10 1300 7934
20 800 7369
30 950 7900
179
9
178
179
9/17/2019
81
180
every system ...
181
... I've worked on
180
181
9/17/2019
82
182
struggles with cAsE
183
no correlation ☺
but its my fault
182
183
9/17/2019
83
184
SQL> select surname
2 from names;
SURNAME
------------------------------
jones
brown
SMITH
sigh...
185
SQL> select initcap(surname)
2 from names;
SURNAME
------------------------------
Jones
Brown
Smith
Mcdonald
184
185
9/17/2019
84
186
and it just gets worse...
187
SQL> select *
2 from customers
3 where cust_name = 'ADAMS';
COUNTRY CREATED CUST_NAME
------------ --------- ------------
AUS 07-NOV-16 ADAMS
186
187
9/17/2019
85
188
SQL> select *
2 from customers
3 where upper(cust_name) = 'ADAMS';
COUNTRY CREATED CUST_NAME
------------ --------- ------------
AUS 07-NOV-16 Adams
AUS 07-NOV-16 ADAMS
AUS 07-NOV-16 adams
189
SQL> select * from customers
2 where upper(cust_name) = 'ADAMS';
188
189
9/17/2019
86
191
SQL> select column_name
2 from user_ind_columns
3 where index_name = 'CUST_IX';
COLUMN_NAME
------------------------------
CUST_NAME
SQL> select * from customers
2 where upper(cust_name) = 'ADAMS';
-------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
-------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 152 |
|* 1 | TABLE ACCESS FULL| CUSTOMERS | 1 | 152 |
-------------------------------------------------------
190
191
9/17/2019
87
192
SQL> create index cust_ix
2 on customers ( cust_name );
Index created.
SQL> create index cust_ix2
2 on customers ( upper(cust_name) );
Index created.
193
DML slower
more contention
more redo/undo
192
193
9/17/2019
88
194
"not my problem"
195
194
195
9/17/2019
89
196
SQL> alter table customers shrink space;
*
ERROR at line 1:
ORA-10631: SHRINK clause should not be specified
197
a better way
196
197
9/17/2019
90
198
column level collation
199
?
198
199
9/17/2019
91
200
SQL> CREATE TABLE CUSTOMERS
2 (
3 COUNTRY VARCHAR2(128),
4 CREATED DATE,
5 CUST_NAME VARCHAR2(150) COLLATE BINARY_CI
6 );
Table created.
"case insenstive"
201
SQL> create index cust_ix
2 on customers ( cust_name);
Index created.
SQL> set autotrace traceonly explain
SQL> select * from customers
2 where cust_name = 'ADAMS';
-----------------------------------------------------------------
| Id | Operation | Name | Rows |
-----------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| CUSTOMERS | 1 |
|* 2 | INDEX RANGE SCAN | CUST_IX | 1 |
-----------------------------------------------------------------
200
201
9/17/2019
92
202
"what is so special about that?"
203
SQL> select * from customers
2 where cust_name = 'ADAMS';
COUNTRY CREATED CUST_NAME
------------ --------- ----------------
AUS 07-NOV-16 Adams
AUS 08-NOV-16 ADAMS
AUS 09-NOV-16 adams
202
203
9/17/2019
93
204
binary_ci
SQL> select * from customers
2 where cust_name = 'ADAMS';
COUNTRY CREATED CUST_NAME
------------ --------- ------------
AUS 07-NOV-16 Adams
AUS 08-NOV-16 ADAMS
AUS 09-NOV-16 adams
205
binary_ai
SQL> select * from customers
2 where cust_name = 'ADAMS';
COUNTRY CREATED CUST_NAME
------------ --------- -----------
AUS 07-NOV-16 Adams
AUS 08-NOV-16 ADAMS
AUS 09-NOV-16 adams
AUS 10-NOV-16 adáms
adáms
204
205
9/17/2019
94
206
column | table | user
207
SQL> alter table people default collation binary_ai;
new columns only
206
207
9/17/2019
95
208
10
209
query block naming
208
209
9/17/2019
96
210
C#, C++ ESB Tuxedo
Weblogic
Stored
Procedure
211
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;
}
}
210
211
9/17/2019
97
212
no comments
212
213
9/17/2019
98
214
"C# is self-documenting"
215
SQL can be complex
214
215
9/17/2019
99
216
SQL should "self document"
217
query blocks = self-documenting SQL
216
217
9/17/2019
100
218
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
219
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 |
218
219
9/17/2019
101
220
?
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 |
221
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
220
221
9/17/2019
102
222
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
223
last
222
223
9/17/2019
103
224
225
225
224
225
9/17/2019
104
226
"talking" to your database
... makes it faster
227
example
226
227
9/17/2019
105
228
STORES
CUSTOMERS
SALES
229
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
hash outer join ?
nested loop ?
STORES first ?
sort merge ?
228
229
9/17/2019
106
230
---------------------------------------------------
| 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 |
---------------------------------------------------
231
can we do better ?
add indexes ?
rewrite query ?
result cache ?
materialized view ?
230
231
9/17/2019
107
232
share your knowledge with the db
oc04.sql
233
wrap up
232
233
9/17/2019
108
234
SQL
235
very cool
234
235
9/17/2019
109
236
very powerful
237
less code
236
237
9/17/2019
110
238
never too early to start
238
239
9/17/2019
111
240
Proven Ways to Make Applications Slower and Less Secure [THT4796]
Tuesday, September 17, 04:30 PM - 04:50 PM, The Exchange - Theater 3
The Best Oracle Database Feature Ever Invented [THT4798]
Wednesday, September 18, 10:15 AM - 10:35 AM, The Exchange - Theater 3
Flashback - Not Just for DBAs
Wednesday, September 18, 04:00 PM - 04:45 PM, Moscone South - Room 306
PL/SQL: Still the Best Data Access Language
Thursday, September 19, 12:15 PM - 01:00 PM, Moscone South - Room 155A
241
Have a great OpenWorld !
youtube youtube.com/c/ConnorMcDonaldOracle
blog connor-mcdonald.com
twitter @connor_mc_d
240
241

Mais conteúdo relacionado

Semelhante a OOW19 - Ten Amazing 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
 
APAC Groundbreakers 2019 - Perth/Melbourne
APAC Groundbreakers 2019 - Perth/Melbourne APAC Groundbreakers 2019 - Perth/Melbourne
APAC Groundbreakers 2019 - Perth/Melbourne Connor McDonald
 
SQL and PLSQL features for APEX Developers
SQL and PLSQL features for APEX DevelopersSQL and PLSQL features for APEX Developers
SQL and PLSQL features for APEX DevelopersConnor McDonald
 
Latin America Tour 2019 - 10 great sql features
Latin America Tour 2019  - 10 great sql featuresLatin America Tour 2019  - 10 great sql features
Latin America Tour 2019 - 10 great sql featuresConnor McDonald
 
Sangam 2019 - The Latest Features
Sangam 2019 - The Latest FeaturesSangam 2019 - The Latest Features
Sangam 2019 - The Latest FeaturesConnor McDonald
 
ITOUG 2019 - 18c, 19c features
ITOUG 2019 - 18c, 19c featuresITOUG 2019 - 18c, 19c features
ITOUG 2019 - 18c, 19c featuresConnor McDonald
 
SQL techniques for faster applications
SQL techniques for faster applicationsSQL techniques for faster applications
SQL techniques for faster applicationsConnor 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
 
12c for Developers - Feb 2014
12c for Developers - Feb 201412c for Developers - Feb 2014
12c for Developers - Feb 2014Connor McDonald
 
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
 
Sangam 19 - Analytic SQL
Sangam 19 - Analytic SQLSangam 19 - Analytic SQL
Sangam 19 - Analytic SQLConnor 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
 
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
 
Oracle Database 12c Application Development
Oracle Database 12c Application DevelopmentOracle Database 12c Application Development
Oracle Database 12c Application DevelopmentSaurabh K. Gupta
 
Connor McDonald 11g for developers
Connor McDonald 11g for developersConnor McDonald 11g for developers
Connor McDonald 11g for developersInSync Conference
 
Connor McDonald Partitioning
Connor McDonald PartitioningConnor McDonald Partitioning
Connor McDonald PartitioningInSync Conference
 
Using SQL to process hierarchies
Using SQL to process hierarchiesUsing SQL to process hierarchies
Using SQL to process hierarchiesConnor 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
 

Semelhante a OOW19 - Ten Amazing 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
 
APAC Groundbreakers 2019 - Perth/Melbourne
APAC Groundbreakers 2019 - Perth/Melbourne APAC Groundbreakers 2019 - Perth/Melbourne
APAC Groundbreakers 2019 - Perth/Melbourne
 
SQL and PLSQL features for APEX Developers
SQL and PLSQL features for APEX DevelopersSQL and PLSQL features for APEX Developers
SQL and PLSQL features for APEX Developers
 
Latin America Tour 2019 - 10 great sql features
Latin America Tour 2019  - 10 great sql featuresLatin America Tour 2019  - 10 great sql features
Latin America Tour 2019 - 10 great sql features
 
Sangam 2019 - The Latest Features
Sangam 2019 - The Latest FeaturesSangam 2019 - The Latest Features
Sangam 2019 - The Latest Features
 
ITOUG 2019 - 18c, 19c features
ITOUG 2019 - 18c, 19c featuresITOUG 2019 - 18c, 19c features
ITOUG 2019 - 18c, 19c features
 
SQL techniques for faster applications
SQL techniques for faster applicationsSQL techniques for faster applications
SQL techniques for faster applications
 
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
 
12c for Developers - Feb 2014
12c for Developers - Feb 201412c for Developers - Feb 2014
12c for Developers - Feb 2014
 
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
 
Sangam 19 - Analytic SQL
Sangam 19 - Analytic SQLSangam 19 - Analytic SQL
Sangam 19 - Analytic SQL
 
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
 
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
 
KScope19 - SQL Features
KScope19 - SQL FeaturesKScope19 - SQL Features
KScope19 - SQL Features
 
Oracle Database 12c Application Development
Oracle Database 12c Application DevelopmentOracle Database 12c Application Development
Oracle Database 12c Application Development
 
Connor McDonald 11g for developers
Connor McDonald 11g for developersConnor McDonald 11g for developers
Connor McDonald 11g for developers
 
Connor McDonald Partitioning
Connor McDonald PartitioningConnor McDonald Partitioning
Connor McDonald Partitioning
 
Using SQL to process hierarchies
Using SQL to process hierarchiesUsing SQL to process hierarchies
Using SQL to process hierarchies
 
Analytic SQL Sep 2013
Analytic SQL Sep 2013Analytic SQL Sep 2013
Analytic SQL Sep 2013
 
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
 

Mais de Connor McDonald

Sangam 19 - PLSQL still the coolest
Sangam 19 - PLSQL still the coolestSangam 19 - PLSQL still the coolest
Sangam 19 - PLSQL still the coolestConnor McDonald
 
Sangam 19 - Successful Applications on Autonomous
Sangam 19 - Successful Applications on AutonomousSangam 19 - Successful Applications on Autonomous
Sangam 19 - Successful Applications on AutonomousConnor 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
 
OOW19 - Slower and less secure applications
OOW19 - Slower and less secure applicationsOOW19 - Slower and less secure applications
OOW19 - Slower and less secure applicationsConnor 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 - Flashback
Latin America tour 2019 -  FlashbackLatin America tour 2019 -  Flashback
Latin America tour 2019 - FlashbackConnor 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 - 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
 
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
 
APEX Connect 2019 - array/bulk processing in PLSQL
APEX Connect 2019 - array/bulk processing in PLSQLAPEX Connect 2019 - array/bulk processing in PLSQL
APEX Connect 2019 - array/bulk processing in PLSQLConnor McDonald
 
APEX Connect 2019 - successful application development
APEX Connect 2019 - successful application developmentAPEX Connect 2019 - successful application development
APEX Connect 2019 - successful application developmentConnor McDonald
 

Mais de Connor McDonald (15)

Flashback ITOUG
Flashback ITOUGFlashback ITOUG
Flashback ITOUG
 
Sangam 19 - PLSQL still the coolest
Sangam 19 - PLSQL still the coolestSangam 19 - PLSQL still the coolest
Sangam 19 - PLSQL still the coolest
 
Sangam 19 - Successful Applications on Autonomous
Sangam 19 - Successful Applications on AutonomousSangam 19 - Successful Applications on Autonomous
Sangam 19 - Successful Applications on Autonomous
 
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
 
OOW19 - Slower and less secure applications
OOW19 - Slower and less secure applicationsOOW19 - Slower and less secure applications
OOW19 - Slower and less secure applications
 
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 - Flashback
Latin America tour 2019 -  FlashbackLatin America tour 2019 -  Flashback
Latin America tour 2019 - Flashback
 
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 - 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
 
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
 
APEX Connect 2019 - array/bulk processing in PLSQL
APEX Connect 2019 - array/bulk processing in PLSQLAPEX Connect 2019 - array/bulk processing in PLSQL
APEX Connect 2019 - array/bulk processing in PLSQL
 
APEX Connect 2019 - successful application development
APEX Connect 2019 - successful application developmentAPEX Connect 2019 - successful application development
APEX Connect 2019 - successful application development
 

Último

Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 

Último (20)

Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 

OOW19 - Ten Amazing SQL features

  • 1. 9/17/2019 1 Copyright © 2019 Oracle and/or its affiliates. 2 Connor McDonald 1 2
  • 3. 9/17/2019 3 5 5 6 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 :-) 5 6
  • 4. 9/17/2019 4 7 etc... facebook bit.ly/facebook-connor linkedin bit.ly/linkedin-connor instagram bit.ly/instagram-connor slideshare bit.ly/slideshare-connor 8 8https://asktom.oracle.com 7 8
  • 10. 9/17/2019 10 21 why talk about SQL # 1 22 NoSQL non relational 21 22
  • 12. 9/17/2019 12 25 developers love cool stuff 26 MICROSERVICES 25 26
  • 13. 9/17/2019 13 27 SQL is microservices ! 28 "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' 27 28
  • 15. 9/17/2019 15 31 SQL is entirely APIs ! 32 "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 32
  • 17. 9/17/2019 17 43 being a smart-ass 44 we can do anything ... 43 44
  • 18. 9/17/2019 18 45 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) 46 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 ) Ack: Anton Scheffer, https://technology.amis.nl 45 46
  • 19. 9/17/2019 19 47 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; 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 48 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 ----------- sud.sql 47 48
  • 20. 9/17/2019 20 49 100% % of developers that will need to solve Sudoku as part of their job 50 100% % of developers that need to get real work done 49 50
  • 26. 9/17/2019 26 61 "Employee salary list, plus department total, plus grand total" 62 62 61 62
  • 27. 9/17/2019 27 63 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 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 64 from 3 to 2 rollup 63 64
  • 28. 9/17/2019 28 65 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 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 66 still messy... 65 66
  • 29. 9/17/2019 29 67 EMPNO SAL DEPTNO ---------- ---------- ---------- 7782 2450 10 7839 5000 10 7934 1300 10 7566 2975 20 7902 3000 20 7876 1100 20 7369 800 20 DEPTNO SUM(SAL) ---------- ---------- 10 8750 20 10875 30 9400 29025 7782 2450 10 7839 5000 10 7934 1300 10 7566 2975 20 10 8750 68 from 2 to 1 67 68
  • 30. 9/17/2019 30 69 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 29025 70 all totals are possible 69 70
  • 31. 9/17/2019 31 71 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 72 totally customisable 71 72
  • 32. 9/17/2019 32 73 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 74 3 73 74
  • 33. 9/17/2019 33 75 error logging 76 SQL> insert into MY_TABLE 2 select * 3 from MY_HUGE_GREAT_FAT_TABLE;MY_HUGE_GREAT_FAT_TABLE; 75 76
  • 36. 9/17/2019 36 81 82 SQL> insert into MY_TABLE 2 select * 3 from MY_HUGE_GREAT_FAT_TABLE; Elapsed: 06:12:34.00 81 82
  • 37. 9/17/2019 37 83 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 84 84 83 84
  • 39. 9/17/2019 39 87 SQL> select count(*) from MY_TABLE; COUNT(*) ---------- 0 88 what we would like 87 88
  • 41. 9/17/2019 41 91 hard 92 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" 91 92
  • 43. 9/17/2019 43 95 DBMS_ERRLOG.CREATE_ERROR_LOG ( dml_table_name IN VARCHAR2, err_log_table_name IN VARCHAR2 := NULL, err_log_table_owner IN VARCHAR2 := NULL, ... 96 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) 95 96
  • 45. 9/17/2019 45 99 add to EMP from NEW_DATA 100 SQL> select * from NEW_DATA; EMPNO SAL DEPTNO ---------- ---------- ---------- 1000 5000 20 100X 3550 10 2000 2500 50 7934 4000 20 non-numeric no dept 50 duplicate 99 100
  • 46. 9/17/2019 46 101 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. 50 102 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 101 102
  • 48. 9/17/2019 48 105 105 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 106 bookings by hour conventional outer join 105 106
  • 49. 9/17/2019 49 107 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 108 bookings by hour per room 107 108
  • 50. 9/17/2019 50 109 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 110 SQL> select * 2 from timeslots; HR -- 8 9 10 11 12 13 14 15 16 x "Room 1" x "Room 2" ... x "Room n" 109 110
  • 51. 9/17/2019 51 111 partitioned outer join 112 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 111 112
  • 54. 9/17/2019 54 117 WITH last_hire AS ( select deptno, max(hiredate) from emp group by deptno ) select * from last_hire; 118 "who cares?....... more code, same result" 117 118
  • 55. 9/17/2019 55 119 why is it cool ? 120 good solution metaphor 119 120
  • 56. 9/17/2019 56 121 relational is a rigorous model ... 122 relational is the dominant model ... 121 122
  • 57. 9/17/2019 57 123 relational ... can be complicated 124 not our fault 123 124
  • 58. 9/17/2019 58 125 Codd & Date 126 "data is represented as mathematical n-ary relations, an n-ary relation being a subset of the Cartesian product of n domains." 125 126
  • 60. 9/17/2019 60 129 step by step 130 "First, get the total salary paid by each department, then get the average of these totals, then list those departments above that average" SQL ? 129 130
  • 61. 9/17/2019 61 131 "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), 132 "...then get the average of these totals... 6 avg_sal AS ( SELECT AVG(dept_sal) avsal 7 FROM dept_salaries) 131 132
  • 62. 9/17/2019 62 133 "...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; 134 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; 133 134
  • 65. 9/17/2019 65 139 recall: partitioned outer join 140 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"}] 139 140
  • 67. 9/17/2019 67 143 scalar queries 144 SQL> select 2 ( select dname 3 from dept 4 where deptno = e.deptno ) dname, 5 decode(empno, 7499, 6 ( select max(sal) from emp ), 7 -1) 8 from 9 ( select * from emp 10 where sal > 0 ) e 11 where 12 ( select max(hiredate) from emp ) < sysdate 13 / scalar anywhere an expression could be 143 144
  • 68. 9/17/2019 68 149 turn procedural into "relational" 150 List all persons in the STAFF table plus their salary calculated based on CLASS_TYPE column value: = ‘T’ (temp worker) salary is FIXED_PRICE from PART_TIME_PACKAGE table = ‘C’ (contractor) salary is the HRS * HRLY_RATE from CONTRACT_PACKAGE table = ‘P’ (permanent) salary is the ANNUAL_SAL + BONUS from PERM_PACKAGE table 149 150
  • 69. 9/17/2019 69 151 different table per row 152 4 begin 5 for i in ( select * from staff ) loop 6 if i.class_type = 'T' then -- part time 7 select fixed_price 8 into v_sal 9 from part_time_package 10 where id = i.class_id; 11 elsif i.class_type = 'C' then -- contractors 12 select hrs * hrly_rate 13 into v_sal 14 from contract_package 15 where id = i.class_id; 16 elsif i.class_type = 'P' then -- permanent 17 select annual_sal + bonus 18 into v_sal 19 from perm_package 20 where id = i.class_id; 21 end if; 22 dbms_output.put_line(rpad(i.name,20)||lpad(v_sal,10)); 23 end loop; 151 152
  • 70. 9/17/2019 70 153 SQL can still do it 154 SQL> select s.name, 2 case class_type 3 when 'T' then ( 4 select fixed_price 5 from part_time_package 6 where id = s.class_id ) 7 when 'C' then ( 8 select hrs * hrly_rate 9 from contract_package 10 where id = s.class_id ) 11 when 'P' then ( 12 select annual_sal + bonus 13 from perm_package 14 where id = s.class_id ) 15 end sal 16 from staff s; Scalar subquery NAME SAL ------------------------------ ------- JOHN SMITH 123.45 JOE BLOGGS 2435.54 153 154
  • 73. 9/17/2019 73 159 rows to columns, colums to rows 160 "I need sales by product for each quarter....now" 159 160
  • 74. 9/17/2019 74 161 SQL> select product, 2 trunc(txn_date,'Q') mth, 3 sum(quantity) total 4 from SALES 5 group by product,trunc(txn_date,'Q') 6 order by 1,2; PRODUCT MTH TOTAL -------------------- --- ---------- CHAINSAW JAN 251473 CHAINSAW APR 254830 CHAINSAW JUL 251994 CHAINSAW OCT 243748 HAMMER JAN 249889 HAMMER APR 256566 HAMMER JUL 252992 HAMMER OCT 249104 SCREW DRIVER JAN 245988 SCREW DRIVER APR 249219 SCREW DRIVER JUL 252128 SCREW DRIVER OCT 244721 SPADE JAN 242434 SPADE APR 254090 SPADE JUL 259613 ... 161 162
  • 75. 9/17/2019 75 163 "That’s wrong!...surely you know I wanted it ACROSS the page" 163 164
  • 76. 9/17/2019 76 165 pivot clause 166 SQL> select * 2 from (select product, 3 trunc(txn_date,'Q') mth, 4 quantity 5 from sales ) 6 pivot( sum(quantity) for mth in 7 ( 'JAN', 8 'APR', 9 'JUL', 10 'OCT') ) 11 order by 1 12 / PRODUCT 'JAN' 'APR' 'JUL' 'OCT' -------------------- ---------- ---------- ---------- ---------- CHAINSAW 251473 254830 251994 243748 HAMMER 249889 256566 252992 249104 SCREW DRIVER 245988 249219 252128 244721 SPADE 242434 254090 259613 248428 WHEEL BARROW 243899 249327 252296 254137 165 166
  • 78. 9/17/2019 78 174 most of us know about analytics 175 SQL> select row_number() OVER ( order by sal ) 2 from emp 3 ... https://bit.ly/analytic_sql 174 175
  • 79. 9/17/2019 79 176 "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" SQL> select deptno, empno, min(sal) 2 from emp 3 group by deptno; ORA-00979: not a GROUP BY expression 177 KEEP extension 176 177
  • 80. 9/17/2019 80 178 SQL> select deptno, min(sal), 2 min(empno) 3 KEEP ( dense_rank FIRST order by sal) empno 4 from emp 5 group by deptno; DEPTNO MIN(SAL) EMPNO ---------- ---------- ---------- 10 1300 7934 20 800 7369 30 950 7900 179 9 178 179
  • 82. 9/17/2019 82 182 struggles with cAsE 183 no correlation ☺ but its my fault 182 183
  • 83. 9/17/2019 83 184 SQL> select surname 2 from names; SURNAME ------------------------------ jones brown SMITH sigh... 185 SQL> select initcap(surname) 2 from names; SURNAME ------------------------------ Jones Brown Smith Mcdonald 184 185
  • 84. 9/17/2019 84 186 and it just gets worse... 187 SQL> select * 2 from customers 3 where cust_name = 'ADAMS'; COUNTRY CREATED CUST_NAME ------------ --------- ------------ AUS 07-NOV-16 ADAMS 186 187
  • 85. 9/17/2019 85 188 SQL> select * 2 from customers 3 where upper(cust_name) = 'ADAMS'; COUNTRY CREATED CUST_NAME ------------ --------- ------------ AUS 07-NOV-16 Adams AUS 07-NOV-16 ADAMS AUS 07-NOV-16 adams 189 SQL> select * from customers 2 where upper(cust_name) = 'ADAMS'; 188 189
  • 86. 9/17/2019 86 191 SQL> select column_name 2 from user_ind_columns 3 where index_name = 'CUST_IX'; COLUMN_NAME ------------------------------ CUST_NAME SQL> select * from customers 2 where upper(cust_name) = 'ADAMS'; ------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | ------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 152 | |* 1 | TABLE ACCESS FULL| CUSTOMERS | 1 | 152 | ------------------------------------------------------- 190 191
  • 87. 9/17/2019 87 192 SQL> create index cust_ix 2 on customers ( cust_name ); Index created. SQL> create index cust_ix2 2 on customers ( upper(cust_name) ); Index created. 193 DML slower more contention more redo/undo 192 193
  • 89. 9/17/2019 89 196 SQL> alter table customers shrink space; * ERROR at line 1: ORA-10631: SHRINK clause should not be specified 197 a better way 196 197
  • 91. 9/17/2019 91 200 SQL> CREATE TABLE CUSTOMERS 2 ( 3 COUNTRY VARCHAR2(128), 4 CREATED DATE, 5 CUST_NAME VARCHAR2(150) COLLATE BINARY_CI 6 ); Table created. "case insenstive" 201 SQL> create index cust_ix 2 on customers ( cust_name); Index created. SQL> set autotrace traceonly explain SQL> select * from customers 2 where cust_name = 'ADAMS'; ----------------------------------------------------------------- | Id | Operation | Name | Rows | ----------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 1 | TABLE ACCESS BY INDEX ROWID BATCHED| CUSTOMERS | 1 | |* 2 | INDEX RANGE SCAN | CUST_IX | 1 | ----------------------------------------------------------------- 200 201
  • 92. 9/17/2019 92 202 "what is so special about that?" 203 SQL> select * from customers 2 where cust_name = 'ADAMS'; COUNTRY CREATED CUST_NAME ------------ --------- ---------------- AUS 07-NOV-16 Adams AUS 08-NOV-16 ADAMS AUS 09-NOV-16 adams 202 203
  • 93. 9/17/2019 93 204 binary_ci SQL> select * from customers 2 where cust_name = 'ADAMS'; COUNTRY CREATED CUST_NAME ------------ --------- ------------ AUS 07-NOV-16 Adams AUS 08-NOV-16 ADAMS AUS 09-NOV-16 adams 205 binary_ai SQL> select * from customers 2 where cust_name = 'ADAMS'; COUNTRY CREATED CUST_NAME ------------ --------- ----------- AUS 07-NOV-16 Adams AUS 08-NOV-16 ADAMS AUS 09-NOV-16 adams AUS 10-NOV-16 adáms adáms 204 205
  • 94. 9/17/2019 94 206 column | table | user 207 SQL> alter table people default collation binary_ai; new columns only 206 207
  • 96. 9/17/2019 96 210 C#, C++ ESB Tuxedo Weblogic Stored Procedure 211 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; } } 210 211
  • 99. 9/17/2019 99 216 SQL should "self document" 217 query blocks = self-documenting SQL 216 217
  • 100. 9/17/2019 100 218 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 219 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 | 218 219
  • 101. 9/17/2019 101 220 ? 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 | 221 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 220 221
  • 102. 9/17/2019 102 222 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 223 last 222 223
  • 104. 9/17/2019 104 226 "talking" to your database ... makes it faster 227 example 226 227
  • 105. 9/17/2019 105 228 STORES CUSTOMERS SALES 229 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 hash outer join ? nested loop ? STORES first ? sort merge ? 228 229
  • 106. 9/17/2019 106 230 --------------------------------------------------- | 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 | --------------------------------------------------- 231 can we do better ? add indexes ? rewrite query ? result cache ? materialized view ? 230 231
  • 107. 9/17/2019 107 232 share your knowledge with the db oc04.sql 233 wrap up 232 233
  • 111. 9/17/2019 111 240 Proven Ways to Make Applications Slower and Less Secure [THT4796] Tuesday, September 17, 04:30 PM - 04:50 PM, The Exchange - Theater 3 The Best Oracle Database Feature Ever Invented [THT4798] Wednesday, September 18, 10:15 AM - 10:35 AM, The Exchange - Theater 3 Flashback - Not Just for DBAs Wednesday, September 18, 04:00 PM - 04:45 PM, Moscone South - Room 306 PL/SQL: Still the Best Data Access Language Thursday, September 19, 12:15 PM - 01:00 PM, Moscone South - Room 155A 241 Have a great OpenWorld ! youtube youtube.com/c/ConnorMcDonaldOracle blog connor-mcdonald.com twitter @connor_mc_d 240 241