sql design patterns advanced sql programming idioms

Post on 17-Dec-2015

237 Views

Category:

Documents

3 Downloads

Preview:

Click to see full reader

TRANSCRIPT

SQL Design Patterns

Advanced SQL programming idioms

Genesis

C++ worldAdvanced C++ Programming Styles and

Idioms, by James O. Coplien Design Patterns: Elements of Reusable Object-

Oriented Software by Erich Gamma et al

SQLSQL for Smarties by Joe CelkoSQL Cookbook by Anthony Molinaro The Art of SQL

by Stephane Faroult, Peter Robson

What is a SQL Pattern?

A common design vocabulary A documentation and learning aid An adjunct to existing design methods A target for refactoring Large range of granularity -- from very general design principles to language-specific idioms

List of Patterns

CountingConditional summationInteger generatorString/Collection decompositionList AggregateEnumerating pairsEnumerating setsInterval coalesce

Discrete interval samplingUser-defined aggregatePivotSymmetric differenceHistogramSkyline queryRelational divisionOuter unionComplex constraintNested intervalsTransitive closureHierarchical total

Symmetric Difference

A = B ?

Isn’t it Equality operator ?

Venn diagram

A\B

B\AA∩B

(A \ B) ∪ (B \ A)

(A ∪ B) \ (A ∩ B)

SQL Query

( select * from A minus select * from B) union all ( select * from B minus select * from A)

Test

create table A asselect obj# id, name from sys.obj$where rownum < 100000;

create table B asselect obj# id, name from sys.obj$where rownum < 100010;

Execution Statistics

Anti Join Transformation

convert_set_to_join = true:

select * from A

where (col1,col2,…) not in (select col1,col2,… from B)

union all

select * from B

where (col1,col2,…) not in (select col1,col2,… from A)

Execution Statistics

Optimization continued…

CREATE INDEX A_id_name ON A(id, name); CREATE INDEX B_id_name ON B(id, name);

_hash_join_enabled = false_optimizer_sortmerge_join_enabled = falseor/*+ use_nl(@"SEL$74086987" A)    use_nl(@"SET$D8486D66" B)*/

Symmetric Difference via Aggregation

select * from (  select id, name,     sum(case when src=1 then 1 else 0 end) cnt1,     sum(case when src=2 then 1 else 0 end) cnt2   from (     select id, name, 1 src from A     union all    select id, name, 2 src from B  ) group by id, name)where cnt1 <> cnt2

Execution Statistics

Equality checking via Aggregation

1. Is there any difference? (Boolean).2. What are the rows that one table contains, and the other doesn't?

|| orahash 267629

|| orahash 512259|| orahash 334382|| orahash 592731

+++=1523431

Relational Division

 Name  Steve Pete  Kate 

x Language 

 SQL 

 Java 

=

 Name   Language 

 Steve   SQL 

 Pete   Java 

 Kate   SQL 

 Steve   Java 

 Pete   SQL 

 Kate   Java 

JobApplicants

JobRequirements

ApplicantSkills

Dividend, Divisor and Quotient

 Name  Language  Steve   SQL 

 Pete   Java 

 Kate   SQL 

 Kate   Java 

/

ApplicantSkills

 Language 

 SQL 

 Java 

=

JobRequirements

? Name 

 Kate 

Remainder

Is it a common Pattern?

Not a basic operator in RA or SQLInformally:

“Find job applicants who meet all job requirements”

compare with:

“Find job applicants who meet at least one job requirement”

Set Union Query

Given a set of sets, e.g {{1,3,5},{3,4,5},

{5,6}}Find their union:

SELECT DISTINCT elementFROM Sets

 ID  ELEMENT  1   1 

 1   3  1   5  2   3  2   4  2   5  3   5  3   6 

Sets

Set Intersection

Given a set of sets, e.g {{1,3,5},{3,4,5},

{5,6}}Find their intersection?

 ID  ELEMENT  1   1 

 1   3  1   5  2   3  2   4  2   5  3   5  3   6 

Sets

It’s Relational Division Query!

“Find Elements which belong to all sets” compare with:

“Find Elements who belong to at least one set”

 ID  ELEMENT  1   1  1   3  1   5  2   3  2   4  2   5  3   5  3   6 

/

 ID 

 1 

 2 

 3 

= ELEMENT 

 5 

Implementation (1)

πName(ApplicantSkills) x JobRequirements  Name  Language

  Steve   SQL 

 Pete   Java 

 Kate   SQL 

 Steve   Java 

 Pete   SQL 

 Kate   Java 

Implementation (2)

Applicants who are not qualified:

πName ( πName(ApplicantSkills) x JobRequirements

- ApplicantSkills

)

Implementation (3)

Final Query:

πName (ApplicantSkills) -

πName ( ApplicantSkills -

πName(ApplicantSkills) x JobRequirements )

Implementation in SQL (1)select distinct Name from ApplicantSkillsminusselect Name from ( select Name, Language from ( select Name from ApplicantSkills ), ( select Language from JobRequirements ) minus select Name, Language from ApplicantSkills)

Implementation in SQL (2)

select distinct Name from ApplicantSkills i

where not exists (

select * from JobRequirements ii

where not exists (

select * from ApplicantSkills iii

where iii.Language = ii.Language

and iii.Name = i.Name

)

)

Implementation in SQL (3)

“Name the applicants such that for all job requirements there exists a corresponding entry in the applicant skills”

“Name the applicants such that there is no job requirement such that there doesn’t exists a corresponding entry in the applicant skills”

“Name the applicants for which the set of all job skills is a subset of their skills”

Implementation in SQL (4)

select distinct Name from ApplicantSkills i

where

(select Language from JobRequirements ii

where ii.Name = i.Name)

in

(select Language from ApplicantSkills)

Implementation in SQL (5)

A ⊆ B A \ B = ∅

select distinct Name from ApplicantSkills iwhere not exists ( select Language from ApplicantSkills minus select Language from JobRequirements ii where ii.Name = i.Name)

Implementation in SQL (6)

select Name from ApplicantSkills s, JobRequirements r

where s.Language = r.Language

group by Name

having count(*) = (select count(*) from

JobRequirements)

Book

top related