3 SQL InformationssystemefürIngenieure Herbstsemester 2016 “SQL is intergalactic data speak.” -- Michael Stonebraker “If we adopt Oracle [for our SQL tutorial], we don’t have to [ … ] pretend that SQL is a standard.” -- Philip Greenspun “SQL ≠ The Relational Model.” -- Christopher Date “In theory, there is no difference between practice and theory. But in practice, there is.” -- Jan L.A. van de Snepscheut R.Marti ZieldesKapitels • Kenntnisder"Datensprache"SQLzurDefinition,ManipulationundAbfragevon Datenbanken,die(mehrodermindergetreu)aufdemRelationenmodellbasieren. • InsbesonderesolltenSieinderLagesein – nicht-trivialeAnfragenübermehrere(vorgegebene)Tabellen(≈Relationen)zuformulieren – (einfache)ManipulationenvonDatenin(vorgegebenen)Tabellendurchzuführen,d.h.neueDatenzu Tabellenhinzufügen,sowiebestehendeDateninTabellenverändernoderlöschen – Eine(vorgegebene)DefinitionvonTabellenzuverstehen,inklusivederWirkungsweisederwichtigsten Integritätsbedingungen(notnull,primarykeyundforeignkey) GrundfürdieVermittlungdiesesStoffs • SQLwirdseitüber25JahreninderPraxiseingesetztundistweitverbreitet– auchheutenoch,trotzbekannterLimitationendesRelationenmodells • DerEinflussvonSQListauchinSprachenfür"modernere"Datenbanksystemezuspüren, z.B.inOQL(fürobjektierteDatenbanken),inXQuery(fürXMLDaten),sowieinHiveQL(für verteilte"BigData"File-SystemewieHadoopHDFS) R.Marti InformationssystemefürIngenieure2016 – 3SQL 2 GeschichtevonSQL (StructuredQueryLanguage) 1974 IBM Research:SEQUEL-XRM(StructuredEnglish-likeQueryLanguage) 1976 IBM Research:SEQUEL-2inSystemR 1980 RSI(RelationalSoftwareInc.,heute:Oracle):Oracle V2alserstes kommerziellesSQL-Produkt,basierendaufIBMResearchPublikationen 1981 1983 IBM:SQL/DS IBM:DB2 fürMVSBetriebssystem(1983) 1986 ANSI/ISO:SQL-86(späterSQL-89)Standard,ca.150Seiten 1992 ANSI/ISO:SQL-92(SQL2)Standard,ca.600Seiten allg.Konsistenzbedingungen(nievollrealisiert!),CLI(Call LevelInterface) 1999 ANSI/ISO:SQL:1999(SQL3)Standard,ca.3000Seiten verschiedeneLevels,insbesondererelevant:CoreSQL:1999 Objekt-orientierteErweiterungen,RekursiveAnfragen,ErweiterungenfDatenanalyse(OLAP) ...andthe storycontinues:SQL:2003,SQL:2006,SQL:2008,SQL:2011,... see alsohttp://en.wikipedia.org/wiki/SQL R.Marti InformationssystemefürIngenieure2016 – 3SQL 3 GeschichtevonSQL:DonChamberlin Geschichte/3 • DonChamberlinholdsaPh.D.fromStanfordUniversity. I Don Chamberlin holds a Ph.D. from • HeworkedatAlmadenResearchCenterdoingresearch Stanford University. ondatabaselanguagesandsystems. I He worked at Almaden Research Center doing research on database languages and systems. • HewasamemberoftheSystemRresearchteam I He was a member of the System R research team that developed much of today’s thatdevelopedmuchoftoday’srelationaldatabase technology. • relational database technology I He designed the original SQL database language. I In 2005 Don Chamberlin received an honory doctoral degree from the University of Zürich for his work on SQL. HedesignedtheoriginalSQLdatabaselanguage. http://www.almaden.ibm.com/cs/people/chamberlin/ • In2005,DonChamberlinreceivedanhonorydoctoraldegreefromtheUniversity ofZurichforhisworkonSQL. InfO12, SQL 4/63 M. Böhlen, ifi@uzh • seealsohttp://www.almaden.ibm.com/cs/people/chamberlin/ R.Marti InformationssystemefürIngenieure2016 – 3SQL 4 SQLTerminologie(imVergleichzumRelationenmodell) • SQL basiertzwaraufdenKonzeptendesRelationenmodells,verwendetaberin vielenBereicheneineeigene(oft"vereinfachte")Terminologie,insbesondere R.Marti InformationssystemefürIngenieure2016 – 3SQL 5 UnterschiedezwischenSQLunddemRelationenmodell SQL weichtteilweisevonKonzeptendesRelationenmodellsab. • EineRelation(inderMathematikwieimDatenbank-Bereich)isteineMenge(set),d.h., DuplikatevonTupelnsindverboten. EineSQLTabelleisteineMulti-Menge(multiset,auchbag), d.h.,DuplikatevonZeilensindgrundsätzlicherlaubt. Grund:DasEntdeckenvonDuplikatenist(fürgrosseTabellen)"teuer". • In SQL istdieReihenfolgederAttribute(columns)einerTabellefix – gemässDefinitionin derjeweiligenCREATE TABLE Anweisung. • IneinerSQLSELECT AnweisungkanneinAttribut(column)mitgleichemNamenmehrfach auftreten– esseidenn,dieSELECT AnweisungistTeileinerView-Definition.Solche AttributemüssenmitdemNamenderjeweiligenTabellequalifiziert werden,z.B. R.A stehtfürAttributA inTabelleR,S.A fürAttributA inTabelleS. R.Marti InformationssystemefürIngenieure2016 – 3SQL 6 PlayersimSQLDBMSMarkt • "Elephants"(inalphabetischerReihenfolge) – IBMmitDB210.5(forLinux/Unix/Windows)/DB211forz/OS – MicrosoftmitSQLServer2014/SQLServer2016 – OraclemitOracle12c • "NichePlayers",z.B – Teradata – SAPHana – Sybase • PublicDomain,z.B. – MySQL5.7 – PostgreSQL9.6 – MonetDB • DieSQLVersionendieserProdukte – habeneinengemeinsamenKern(≈CoreSQL:1999≈SQL1989) – kommerzielleProduktehabenmeisteigeneErweiterungen,umsichzupositionieren R.Marti InformationssystemefürIngenieure2016 – 3SQL 7 SQLÜberblick • DataDefinitionLanguage(DDL) – DefinitionvonTabellen,Sichten:CREATE TABLE,CREATE VIEW,ALTER TABLE – DefinitionvonIntegritätsbedingungen:CREATE ASSERTION • DataManipulationLanguage(DML) – Datenbank-Anfragen:SELECT – Datenbank-Änderungen:INSERT,UPDATE,DELETE • DataControlLanguage(DCL) – z.B.Autorisierung:GRANT,REVOKE • SchnittstellenzuProgrammiersprachen – viaPrecompiler:EmbeddedSQL,DynamicSQL,SQLJ – viaprozeduraleSchnittstelle:CLI(z.B.ODBCfürC),JDBCfürJava • ProzeduraleElemente:SQL/PSM(bzw.PL/SQLinOracle,…) – z.B.CREATE PROCEDURE R.Marti InformationssystemefürIngenieure2016 – 3SQL 8 DefinitionvonTabellen(üblicheForm):Bsp.mitSchlüsselkandidaten CREATE TABLE Products ( PrdNo INTEGER NOT NULL, PrdDescr VARCHAR(30) NOT NULL, Weight FLOAT NOT NULL CHECK (Weight > 0.0), ... ► CONSTRAINT PK_Products PRIMARY KEY (PrdNo), CONSTRAINT AK_Products UNIQUE (PrdDescr) ); R.Marti InformationssystemefürIngenieure2016 – 3SQL 9 Beispiel:Lieferdatenbank Products PRIMARY KEY (PrdNo) beimEinfügen(INSERT)einesTupels in Products wirdüberprüft,ob PrdNo eindeutigbleibt PrdNo PrdDescr 901 'Mouse*Logitech' 902 'Hard*Drive*LaCie' 903 'Speaker*Bose' Weight Price Warehouse Stock 20 20.00 'Zürich' 1500 450.00 'Bern' 700 600.00 'Luzern' 10000 400 100 ebensobeimÄndern (UPDATE) einerPrdNo R.Marti InformationssystemefürIngenieure2016 – 3SQL 10 DefinitionvonTabellen(üblicheForm):Bsp.mitFremdschlüssel CREATE TABLE Products ( PrdNo INTEGER NOT NULL, PrdDescr VARCHAR(30) NOT NULL, Weight FLOAT NOT NULL CHECK (Weight > 0.0), ... üblicheReihenfolgebeiTabellendefinition: CONSTRAINT PK_Products PRIMARY KEY (PrdNo), - Columns CONSTRAINT AK_Products UNIQUE (PrdDescr) (=Attribute) ); - PrimaryKey (=Primärschlüssel) CREATE TABLE Orders ( - UniqueConstraints OrdNo INTEGER NOT NULL, (=übrigeSchlüsselkandidaten) PrdNo INTEGER NOT NULL, - ForeignKeys CusNo INTEGER NOT NULL, (=Fremdschlüssel,sofernvorhanden) ... Status VARCHAR(10) NOT NULL DEFAULT '1 ordered', OrderDate DATETIME NOT NULL, ShipDate DATETIME NOT NULL, CONSTRAINT PK_Orders PRIMARY KEY (OrdNo), CONSTRAINT AK_Orders UNIQUE (OrderDate, PrdNo, CusNo), CONSTRAINT FK_OrderedProducts ► FOREIGN KEY (PrdNo) REFERENCES Products(PrdNo), CONSTRAINT FK_OrderingCustomers FOREIGN KEY (CusNo) REFERENCES Customers(CusNo) ); R.Marti InformationssystemefürIngenieure2016 – 3SQL 11 Beispiel:Lieferdatenbank Products PRIMARY KEY (PrdNo) PrdNo PrdDescr Weight Price Warehouse Stock 901 'Mouse*Logitech' 902 'Hard*Drive*LaCie' 20 20.00 'Zürich' 1500 450.00 'Bern' 903 'Speaker*Bose' 700 600.00 'Luzern' 10000 400 100 beimLöschen(DELETE)einesTupelsinProducts wirdüberprüft, obkeinTupelinOrders diesenWertreferenziert FOREIGN KEY PrdNo REFERENCES Products(PrdNo) Orders OrdNo CusNo PrdNo Qty Amount 67890 101 901 100 1800.00 67891 101 901 100 1800.00 67892 101 902 8 3240.00 67893 102 903 1 R.Marti beimEinfügen(INSERT)einesTupelsinOrders wirdüberprüft, obinProducts einTupelmitdemWertvonPrdNo als Primärschlüsselexistiert Status OrderDate ShipDate ebensobeimÄndern '3*paid' 2013007016 2013007020 (UPDATE)einerPrdNo '3*paid' 2013007021 2013007028 in Orders '1*ordered' 2013009020 9999012031 oderinProducts 480.00 '2*shipped' 2013009020 2013009021 InformationssystemefürIngenieure2016 – 3SQL 12 EBNFNotationzurBeschreibungderSyntax SyntaxElement Syntaxelement,für daseine Definitionanzugeben ist (sog.Nichtterminalsymbol) RESERVED reserviertes Wort,welches im Quelltext sovorkommt (sog.Terminalsymbol) "s" Terminalsymbol s,welches im Quelltext sovorkommt abg Folge von(Nichtterminal- undTerminal-)Symbolen a|b entweder dasSymbola oder dasSymbolb (aber nicht beide) [a] dasSymbola ist optional (0oder 1Vorkommen vona) {a} dasSymbola kann wiederholt werden (0,1oder mehrere Vorkommen vona) Klammern ()werden verwendet umGruppierungen zu kennzeichnen: a |b g bedeutet entweder a oder dieFolge b g (a |b )g bedeutet entweder dieFolge a g oder dieFolge R.Marti InformationssystemefürIngenieure2016 – 3SQL bg 13 EinigeBemerkungenzuSQLSyntax-Konventionen ImdiesemTextwerdenfürreservierteWorteGrossbuchstabenverwendet (z.B.TABLE).Diesistjedochnichtzwingend. EinName(TableName,TableAlias,ColumnName,ColumnAlias)mussmiteinemBuchstaben beginnen,gefolgtvonBuchstaben,ZiffernoderderUnterlänge(underscore)_. EineKonstante(hierLiteral genannt)hatjenachDatentypfolgendeForm - eineFolgevonZiffernmitoderohneVorzeichen,z.B.123 ,-45 - eineFix- oderGleitkommazahl,z.B.6.789 ,-1.23E4 ,+0.1 - einTextderForm'Dies ist ein Text' oder'John''s Home' InSQLspieltGross-/KleinschreibungnurinnerhalbvonText-KonstanteneineRolle! DiefolgendenSchreibweisenvonNamen werdendemzufolgealsidentisch angesehen: FAMILYNAME,familyname,FamilyName undfamilyName. Nichtidentischsindjedochz.B.dieText-Konstanten'SWISS','Swiss' und'swiss' . R.Marti InformationssystemefürIngenieure2016 – 3SQL 14 DefinitionvonTabellen:SyntaxinEBNF TableDef = CREATE TABLE TableName "(" TableElementDef { "," TableElementDef } ")" . TableElementDef = ColumnDef | [ CONSTRAINT ConstraintName ] TableConstraintDef . ColumnDef = ColumnName DataType [ DEFAULT Literal ] { ColumnConstraintDef } . ColumnConstraintDef = NOT NULL | PRIMARY KEY | UNIQUE | CHECK "(" SearchCondition ")" | REFERENCES TableName [ "(" ColumnName ")" ] . TableConstraintDef = ( PRIMARY KEY | UNIQUE ) "(" ColumnList ")" | CHECK "(" SearchCondition ")" | FOREIGN KEY "(" ColumnNameList ")" REFERENCES Table [ "(" ColumnNameList ")" ] . ColumnList = ColumnName { "," ColumnName } . DataType = INTEGER | REAL | CHAR | VARCHAR "(" Length ")" | DATETIME | … . • TableName undColumnName sindNamen,Literal eineKonstante(Zahl,Text,Datum). SearchCondition wirdspäterdefiniert. R.Marti InformationssystemefürIngenieure2016 – 3SQL 15 EinfacheAnfragen:Syntax(vereinfacht,unvollständig) Query = Subquery { ( UNION | INTERSECT | EXCEPT ) [ ALL ] Subquery } [ ORDER BY OrderItem { "," OrderItem } ] . Subquery = SELECT [ DISTINCT ] ( ProjectionList | "*" ) FROM TableExpr { "," TableExpr } [ WHERE SearchCondition ] [ GROUP BY ColumnRef { "," ColumnRef } [ HAVING SearchCondition ] ] . ProjectionList = ScalarExpr [ [ AS ] ColumnAlias ] { "," ScalarExpr [ [ AS ] ColumnAlias ] } . ScalarExpr = ColumnRef | Literal | … . ColumnRef = [ TableName "." ] ColumnName . TableExpr = ( TableName | Subquery ) [ [ AS ] TableAlias ] . OrderItem = { ColumnRef | Integer } [ ASC | DESC ] . R.Marti InformationssystemefürIngenieure2016 – 3SQL 16 SQLAnfragen undRelationenalgebra SeiA einAttributeinerRelationR, B einAttributeinerRelationS undp eineFormel,dieAttributeausdenRelationenR undS referenziert. EineQueryderForm SELECT A, B FROM WHERE R, S p entspricht– sofernkeineDuplikateeliminiertwerdenmüssen– dem Relationenalgebra-Ausdruck pA, B ( sp ( R ´ S ) ) R.Marti InformationssystemefürIngenieure2016 – 3SQL 17 Selektion:BeispielmiteinfachemSelektionsprädikat FindealleZürcherKunden s CusCity = 'Zürich' (Customers) SELECT * FROM Customers WHERE CusCity = 'Zürich' R.Marti InformationssystemefürIngenieure2016 – 3SQL 18 Selektion:BeispielmitzusammengesetztemPrädikat FindealleZürcherKunden,dieunsGeldschulden s CusCity = 'Zürich' Ù BalanceDue > 0 (Customers) SELECT * FROM Customers WHERE CusCity = 'Zürich' AND BalanceDue > 0 R.Marti InformationssystemefürIngenieure2016 – 3SQL 19 Projektion:Beispiel FindeBeschreibung,LagerortundLagerbestandfüralleProdukte p PrdDescr, Warehouse, Stock (Products) SELECT PrdDescr, Warehouse, Stock FROM Products R.Marti InformationssystemefürIngenieure2016 – 3SQL 20 SelektionundProjektion(IntegrierteÜbung) Beschreibung,LagerortundLagerbestand fürProdukte,derenLagerbestand<300 ist p PrdDescr, Warehouse, Stock (s Stock < 300 (Products)) ? R.Marti InformationssystemefürIngenieure2016 – 3SQL 21 Vereinigung:Beispiel Nummer,Beschreibung, GewichtundPreis,sowohl fürbestehendewieauch fürneueProdukte ∪ p PrdNo, PrdDescr, Weight, Price (Products) ∪ NewProducts SELECT FROM UNION SELECT FROM R.Marti PrdNo, PrdDescr, Weight, Price Products PrdNo, PrdDescr, Weight, Price NewProducts InformationssystemefürIngenieure2016 – 3SQL 22 JoinmitKreuzproduktundSelektion:KonkretesBeispiel × p OrdNo, CusNo, PrdNo, Qty, ShipDate, CusName ( s CusNo1 = CusNo ( Orders × r CusNo1 ß CusNo (Customers) ) ) SELECT OrdNo, Orders.CusNo, Qty, ShipDate, CusName FROM Orders, Customers WHERE Orders.CusNo = Customers.CusNo Result_12 OrdNo CusNo PrdNo Qty ShipDate CusName R.Marti 67890 101 901 100 2013)07)20 'Legrand' 67891 101 901 100 2013)07)28 'Legrand' 67892 101 902 8 9999)12)31 'Legrand' 67893 102 903 1 2013)09)21 'Studer' InformationssystemefürIngenieure2016 – 3SQL 23 Modell für Auswertung einfacher SQLAnfragen DieKorrespondenzeinereinfachen SQL-AnfragezurRelationenalgebra bildetdie Basisfüreinkonzeptionelles ModellderAnfrageauswertung: 1. FormedasKreuzproduktderTabelleninderFROM-Klausel. ´ 2. EliminiereZeilen,welchedieWHERE-Klausel nichterfüllen. s 3. EvaluieredieAusdrückeinderSELECT-Klausel. p 4. EliminiereDuplikatefallsDISTINCT spezifiziertwurde. (*) (*):inRelationenalgebra nichtnötig:JedesElementeinerMengekommtnureinmalvor Datenbanksystemeverwenden meisteffizientereStrategien; sowirdz.B.einKreuzproduktnicht vollständigberechnet("materialisiert") wenndiesnichtnötigist. R.Marti InformationssystemefürIngenieure2016 – 3SQL 24 SQLAnfragen:Beispiele(1) ► Selektion Q1 Kunden,dieunsGeldschulden. SELECT CusNo, CusName, CusCity, BalanceDue, Discount FROM WHERE Customers BalanceDue > 0 oder einfacher, abernurfür interaktive Anfragenempfohlen SELECT * FROM WHERE R.Marti Customers BalanceDue > 0 InformationssystemefürIngenieure2016 – 3SQL 25 SQLAnfragen:Beispiele(2) Kreuzprodukt ► +Selektion +Projektion Q2 NamenderKunden,dieeinegelieferte(nochunbezahlte)Bestellung erhaltenhaben,dievorAnfangSeptember2013 erfolgte. pCusName (sCusNo = D Ù Status = '2 shipped' Ù ShipDate < 2013-09-01 (rD ß CusNo (Orders) × Customers)) SELECT CusName FROM Customers, Orders WHERE Orders.CusNo = Customers.CusNo AND Status = '2 shipped' AND ShipDate < DATE '2013-09-01' R.Marti InformationssystemefürIngenieure2016 – 3SQL 26 SQLAnfragen:Beispiele(3) ► Mengendifferenz +Projektion Q3 KundennummernderKunden,vondenenkeineBestellung registriertist. pCusNo (Customers) – pCusNo (Orders) SELECT CusNo FROM Customers EXCEPT SELECT CusNo FROM Orders inOracleMINUS stattEXCEPT inMySQLnichtunterstützt aberaufandereArtlösbar(➛ siehespäter) R.Marti InformationssystemefürIngenieure2016 – 3SQL 27 SQLAnfragen:Beispiele(4) Q4 NamenderKunden,vondenenmindestenseineBestellung registriertist. pCusName ( sCusNo = D ( Customers × rD ß CusNo (Orders) ) ) SELECT Customers.CusName FROM Customers, Orders WHERE Orders.CusNo = Customers.CusNo auchaufandereArtlösbar(➛ siehespäter) R.Marti InformationssystemefürIngenieure2016 – 3SQL 28 SQLAnfragen:Beispiele(5) ► Kreuzproduktvon3Tabellen Q6 NamenderZürcherKunden,dieeinProdukt ausZürichbestellt haben. SELECT Customers.CusName FROM WHERE Customers, Orders, Products Orders.CusNo = Customers.CusNo AND Products.PrdNo = Orders.PrdNo AND Customers.CusCity = 'Zurich' AND Products.Warehouse = 'Zurich' R.Marti InformationssystemefürIngenieure2016 – 3SQL 29 SQLAnfragen:Beispiele(6) VerwendungderJoin-Syntax ► (entsprichtTheta- bzw.Equi-Join) Q6 NamenderZürcherKunden,die einProdukt ausZürichbestellt haben. SELECT Customers.CusName FROM Customers JOIN Orders ON Orders.CusNo = Customers.CusNo JOIN Products ON Products.PrdNo = Orders.PrdNo WHERE AND Customers.CusCity = 'Zurich' AND Products.Warehouse = 'Zurich' Bem.: Esgibtaucheinen NATURAL JOIN Operator, dessenVerwendungaberhöchstensfürinteraktiveAnfragenempfohlenwird. R.Marti InformationssystemefürIngenieure2016 – 3SQL 30 SQLAnfragen:Beispiele(7) Verwendungvon Tabellen-Alias ► (auchKorrelationsvariablegenannt) Q8 NamenvonPaarenvonKunden,dieinderselbenStadtwohnen,mitStadt. pCusName, OtherName, CusCity ( Customers ⋈ OtherCity = CusCity Ù OtherNo > CusNo rOtherNo ß CusNo, OtherName ß CusName, OtherCity ß CusCity ( Customers ) ) SELECT c1.CusName, c2.CusName AS OtherName, c1.CusCity FROM WHERE R.Marti Customers c1, Customers c2 c2.CusCity = c1.CusCity AND c2.CusNo > c1.CusNo InformationssystemefürIngenieure2016 – 3SQL 31 SQLAnfragen:Beispiele(8) ► Join-Syntax+Tabellen-Alias Q6 NamenderZürcherKunden,die einProdukt ausZürichbestellt haben. SELECT c.CusName FROM Customers c JOIN Orders o ON o.CusNo = c.CusNo JOIN Products p ON p.PrdNo = o.PrdNo WHERE AND c.CusCity = 'Zurich' AND p.Warehouse = 'Zurich' R.Marti InformationssystemefürIngenieure2016 – 3SQL 32 EinigeDetailszurSELECTKlausel • DasSymbol* stehtfüralleKolonnenallerTabellenderzugehörigenFROM Klausel. • EskönnenstattKolonnennamenoderKonstantenAusdrückeverwendetwerden,z.B. Qty*Amount*(1–Discount),ABS(-1),CHAR_LENGTH('Chamberlin') FamName || ', ' || FirstName,TRIM(UPPER('Codd ')) • Kolonnenkönnenumbenanntbzw.neubenanntwerden,z.B. Qty*Amount*(1–Discount) AS TotalAmount FamName || ', ' || FirstName AS FullName • WennineinemAusdruck(ScalarExpr)derWerteinerKolonneA einesTupelsNULL ("unbekannt")ist,dannistderWertdesganzenAusdrucksNULL,z.B.wennDiscount denWertNULL hat,dannhatauchQty*Amount*(1–Discount) denWertNULL. • KolonnenkönnendurcheineSubquery,d.h.( SELECT ScalarExpr FROM ... ) berechnet werden,soferndieseSubqueryhöchstens einTupelzurückliefert. FallsdieSubquerykeinTupelliefert,soistderWertNULL (vglspätere Folie). • DasreservierteWortDISTINCT eliminiertDuplikate(vglfolgendeFolie). R.Marti InformationssystemefürIngenieure2016 – 3SQL 33 EliminiationvonDuplikatenmitDISTINCT:Beispiel InwelchenStädten wohnenunsereKunden? p CusCity (Customers) SELECT DISTINCT CusCity FROM Customers SELECT CusCity FROM Customers Result_14 Result_13 CusCity CusCity 'Genève' 'Genève' 'Zürich' R.Marti Relationenmodell(Theorie) EineRelation isteineMenge. SQL(Praxis) 'Zürich' EinTable isteineMulti-Menge. 'Zürich' InformationssystemefürIngenieure2016 – 3SQL 34 WiekönnenDuplikateentstehen? DasResultat einer Anfrage enthält infolgenden Fällen Duplikate: • BeieinerAnfragederFormSELECT * FROM T (mitoderohneWHERE-Klausel)aufeinerTabelle T, fürdiewedereinPRIMARY KEY nocheineUNIQUE Bedingung spezifiziert wurde, undindie mehrereidentischeTupel eingefügtwurden. ⇒ FürjedeTabellesollteeinPRIMARY KEY spezifiziertwerden. • WennnacheinerProjektiondieverbleibendenKolonnenkeinenSchlüsselkandidaten mehr enthalten (vgl.BeispielaufdervorherigenFolie). • BeieinerVereinigungvonzweiTabellenmitUNION ALL. ZurEliminationvonDuplikatenmussSELECT DISTINCT spezifiziertwerden– idealerweise jedochnurdann,wenndiesauchwirklichnötigist. IndenmeistenSystemenwirdbeiSELECT DISTINCT dasResultatnachpotentiellenDuplikaten abgesucht,selbstwenneineAnfragenieDuplikateproduzierenkann! R.Marti InformationssystemefürIngenieure2016 – 3SQL 35 SkalarfunktionenundOperatoren– einunvollständiger Überblick • numerischeOperatoren: NumExpr+NumExpr, NumExpr-NumExpr, NumExpr*NumExpr, NumExpr/NumExpr, ABS(NumExpr), … • Funktionen,dienumerischeWerteliefern: CHAR_LENGTH(StringExpr), POSITION(StringExpr IN StringExpr), … • Funktionen,dieZeichenkettenliefern: • StringExpr || StringExpr SUBSTRING(StringExpr START Pos FOR Len) UPPER(StringExpr) Konkatenation vonZeichenketten TeileinerZeichenkette KonversionzuGrossbuchstaben LOWER(StringExpr) TRIM(StringExpr) CURRENT_USER KonversionzuKleinbuchstaben EliminationvonLeerzeichenvornundhinten Benutzername Funktionen,dieDatumswerteliefern: CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP R.Marti InformationssystemefürIngenieure2016 – 3SQL 36 SubqueriesalsSkalarfunktioninderSELECT-Klausel • EineSELECT-Anweisung kannalsSkalarfunktion betrachtetwerden,fallssieeineTabellebestehendaus höchstenseinerZeilemiteinerSpalteliefert.FallsdasResultateineZeileumfasst,dannistderSkalarder WertderSpalte,sonstistderSkalarderWertNULL.) SomitkanneinesolcheSubqueryauchineinerSELECT-Klausel stehen: SELECT ( SELECT COUNT(*) + 1 FROM Products otherProduct WHERE otherProduct.Price > givenProduct.Price ) AS WhatAmI, givenProduct.Price, givenProduct.PrdDescr FROM Products givenProduct ORDER BY 1 • COUNT(*) isteineAggregatfunktion,welchedieAnzahlTupel ineinerTabellezählt (vgl.spätereFolieüberAggregatfunktionenundderenSyntax,mitBeispielen) • Frage:WasproduziertdieobigeAnfrage?WofürstehtdieKolonneWhatAmI? R.Marti InformationssystemefürIngenieure2016 – 3SQL 37 EinigeDetailszurWHEREKlausel • DieWHERE KlauselgibtdiejenigenTupelzurück,fürwelchedieEvaluationderganzen SearchCondition denWahrheitswertT (fürtrue bzw.wahr)ergibt. Bem.:T sowieF (fürfalse bzw.falsch)sindkeine KonstanteninSQL. • DieSearchCondition beinhaltetals"atomare"BedingungendieüblichenVergleichsoperationen(=,<,<=,>=,<>)sowieVerknüpfungensolcherBedingungenmitAND,OR und NOT: • AusserdemgibtesunteranderemeinigeweitereeinfacheBedingungenwie BETWEEN ScalarExpr AND ScalarExpr sowieScalarExpr LIKE Pattern. R.Marti InformationssystemefürIngenieure2016 – 3SQL 38 VergleichemitNullwerten NULL stehtfür"Wertunbekannt"(allenfallsfür"Wertnichtanwendbar") • DasResultateinesVergleichsinderWHERE KlauselzwischenNULL und – einem"regulären"(nicht-NULL)Wertergibtunbekannt(unknown) – demWertNULL selbstergibtebenfallsunbekannt(unknown) daeinunbekannterWertgleich(bzw.kleiner,grösseroderungleich)wieeinanderer (bekannteroderunbekannter)Wertseinkann! • Dazuwirdeine3-wertigeLogikverwendet,wobei? fürdenlogischenWert"unbekannt" steht. R.Marti InformationssystemefürIngenieure2016 – 3SQL 39 Bereichsprädikate:SyntaxundBeispiel BetweenPredicate = ScalarExpr [ NOT ] BETWEEN ScalarExpr AND ScalarExpr . • Kunden,derenRabattzwischen10und20Prozentliegt . SELECT * FROM Customers WHERE Discount BETWEEN 0.10 AND 0.20 • ObigeFormulierungentsprichtderfolgendenFormulierung: SELECT * FROM Customers WHERE Discount >= 0.10 AND Discount <= 0.20 R.Marti InformationssystemefürIngenieure2016 – 3SQL 40 Mustervergleiche:SyntaxundBeispiele LikePredicate = ColumnRef [ NOT ] LIKE Literal [ ESCAPE Literal ] . wobeiimZeichenketten-LiteralnachLIKE _ füreinbeliebigesZeichensteht % füreinebeliebigeFolgevonZeichen(auchdieleereFolge)steht alleanderenZeichenfürsichselbststehen DasLiteralnachESCAPE definiertein„Escape“-Zeichen,z.B.'\'. • Kunden,derenNamemit‘A‘ beginnt . SELECT * FROM Customers WHERE CusName LIKE 'A%' • Produkte,inderen Beschreibung‘DVD’vorkommt. SELECT * FROM Products WHERE PrdDescr LIKE '%DVD%' • Produkte,deren Beschreibungmit‘P_A’undeinembeliebigenZeichenendet. SELECT * FROM Products WHERE PrdDescr LIKE '%P\_A_' ESCAPE '\' R.Marti InformationssystemefürIngenieure2016 – 3SQL 41 VergleichemitNullwerten:SyntaxundBeispiele NullTest = ColumnRef IS [ NOT ] NULL . • Produkte,derenLagerortunbekanntist . SELECT * FROM Products WHERE Warehouse IS NULL Achtung: ColumnRef = NULL istlegal,ergibtaber unknown,egalwas ColumnRef enthält! • Produkte,derenMengeanLagerbekannt(nichtNULL)ist . SELECT * FROM Products WHERE Stock IS NOT NULL bzw. SELECT * FROM Products WHERE NOT (Stock IS NULL) R.Marti InformationssystemefürIngenieure2016 – 3SQL 42 Subqueries– QuantifizierteVergleiche:Syntax QuantifiedPredicate = ScalarExpr ( "=" | "<>" | "<" | "<=" | ">=" | ">" ) [ ALL | ANY | SOME ] "(" Subquery ")" . Seien x einSkalar, S dasResultateinerSubqueryderForm SELECT y FROM R und q einerderobigenVergleichsoperatoren. Danngilt: x q ANY ( SELECT y FROM R ) x q SOME ( SELECT y FROM R ) sinderfüllt,fallsgilt: $y Î S: x q y x q ALL ( SELECT y FROM R ) isterfüllt,fallsgilt: "y Î S: x q y (esexistierteiny inS sodassx q y ) (füralley inS giltx q y ) Auswertung: ZuerstwirddieSubquery,dieS berechnet,ausgeführt,danachdieäussereQuery, inderenWHERE-KlauselderquantifizierteVergleichauftriff. R.Marti InformationssystemefürIngenieure2016 – 3SQL Empfehlung: QuantifizierteVergleiche vermeiden… 43 Subqueries– QuantifizierteVergleiche:Beipiele QuantifiedPredicate = ScalarExpr ( "=" | "<>" | "<" | "<=" | ">=" | ">" ) [ ALL | ANY | SOME ] "(" Subquery ")" . • KundenmitdemgeringstenRabatt. SELECT * FROM Customers WHERE Discount <= ALL ( SELECT Discount FROM Customers ) • Kunden,dienichtdengeringstenRabatthaben. SELECT * FROM Customers WHERE Discount > SOME ( SELECT Discount FROM Customers ) • NamenallerKundendieeineunbezahlteLieferungerhielten,dievor2014erfolgte: SELECT CusName FROM Customers WHERE CusNo = ANY ( SELECT CusNo FROM Orders WHERE Status = '2 shipped' AND ShipDate < DATE '2014-01-01' ) R.Marti InformationssystemefürIngenieure2016 – 3SQL 44 Subqueries– Mengenzugehörigkeit:Syntax+Beispiele InPredicate = ScalarExpr [ NOT ] IN "(" ( Literal { "," Literal } | Subquery ) ")" . • Kunden,dieinZürich,GenfoderBasel wohnen. eineexpliziteListevonWerten SELECT * FROM Customers WHERE CusCity IN ( 'Zürich', 'Genf', 'Basel' ) • NamenallerKunden,dieeineunbezahlteLieferungerhielten,dievorAnfangSeptember2013 erfolgte. eineSubquery SELECT CusName Resultat:eineRelation FROM Customers WHERE CusNo IN ( SELECT CusNo FROM Orders WHERE Status = '2 shipped' AND ShipDate < DATE '2013-09-01' ) Konzeptionelles Auswertungsmodell: Zuerst wird dieSubquery einmal ausgewertet,danach dieäussere Query. R.Marti InformationssystemefürIngenieure2016 – 3SQL 45 Subqueries– Mengenzugehörigkeit:Semantik InPredicate = ScalarExpr [ NOT ] IN "(" ( Literal { "," Literal } | Subquery ) ")" . • x IN ( c1, c2, … , cn ) istäquivalentzu x = c1 OR x = c2 OR … OR x = cn • x IN ( SELECT y FROM R ) istäquivalentzu x = ANY ( SELECT y FROM R ) • x NOT IN ( SELECT y FROM R ) istäquivalentzu x <> ALL ( SELECT y FROM R ) . R.Marti InformationssystemefürIngenieure2016 – 3SQL 46 Subqueries– Existenz ExistenceTest = [ NOT ] EXISTS "(" Subquery ")" . • NamenallerKunden,dieeineunbezahlteLieferungerhielten,dievorAnfangSeptember2013 erfolgte. einekorrelierte Subquery SELECT c.CusName FROM Customers c WHERE EXISTS ( SELECT * FROM Orders o WHERE o.CusNo = c.CusNo AND o.Status = '2 shipped' AND o.ShipDate < DATE '2013-09-01' ) • NamenallerKunden,fürdiekeineBestellungregistriertist SELECT c.CusName FROM Customers c WHERE NOT EXISTS ( SELECT * FROM Orders o WHERE o.CusNo = c.CusNo ) Konzeptionelles Auswertungsmodell: Diekorrelierte Subquery wird für jeden Wertvonc.CusNo der äusseren Queryeinmal ausgewertet. R.Marti InformationssystemefürIngenieure2016 – 3SQL 47 SQLAnfragen:Beispiele(9) Mengendifferenz: kannstattmitEXCEPT ► durchNOT EXISTS ausgedrücktwerden Q3 KundennummernderKunden,vondenenkeineBestellung registriertist. pCusNo (Customers) – pCusNo (Orders) SELECT CusNo FROM Customers WHERE NOT EXISTS SELECT FROM WHERE ( * Orders Orders.CusNo = Customers.CusNo ) R.Marti InformationssystemefürIngenieure2016 – 3SQL 48 Subqueries,derenResultateinSkalarwertist DasResultat einer Subquery ist normalerweise eine Tabelle,d.h.ein BagvonZeilen mit mehreren Spalten. Ingewissen Fällen wissen wir,dass dasResultat ein Bagbestehend aus höchstens einer Zeile mit einer Spalte sein sollte. Dann darf dasResultat der Subquery als Skalarwert betrachtet werden. (FallsdasResultat der Subquery leerist,wird der Skalarwert NULL zurückgegeben.) • Beispiel(skalare SubqueryinWHERE-Klausel): Bestellnummer,LieferdatumundMengeausgelieferterBestellungendesProdukts‘DiskDrive‘. (Annahme:KolonnePrdDescr istSchlüsselkandidatundalsUNIQUE deklariert.) SELECT FROM WHERE AND R.Marti OrdNo, ShipDate, Qty Orders Status = '2 shipped' PrdNo = ( SELECT PrdNo FROM Products WHERE PrdDescr = 'Disk Drive' ) InformationssystemefürIngenieure2016 – 3SQL 49 Scoping-RegelnfürNamenvonKolonnen 1. EinunqualifizierterNameeinerKolonneC ineinerSubqueryQ (bzw.ineinergeschachtelten QueryQ) gehörtzueinerTabelleT inderFROM-KlauseldergleichenSubqueryQ,soferninQ genaueineTabelleT miteineKolonnenamensC existiert. 2. WennesinQ mehrereTabellenmiteinerKolonnenamensC gibt,dannistdieSELECTAnweisungungültig. 3. WennesinQ keineTabellemiteinerKolonnenamensC gibt,dannwirddieSuchenachderzu C gehörigenTabelleinderdieSubqueryQ umfassenden(Sub-)Queryrekursivfortgesetzt (soferneinesolcheexistiert). 4. WennkeineumfassendeQueryexistiert,dannistdieSELECT-Anweisungungültig. • Beispiel:NamenallerKunden,fürdiekeineBestellungregistriertist SELECT CusName FROM Customers WHERE NOT EXISTS ( SELECT * FROM Orders WHERE CusNo = Customers.CusNo ) R.Marti InformationssystemefürIngenieure2016 – 3SQL 50 ZusätzlicheJoin-SyntaxinSQL:1999 NamenallerKunden,dieeinedieeineunbezahlteLieferungerhielten,dievorAnfangSeptember2013 erfolgte SELECT CusName FROM Customers c, ( SELECT CusNo FROM Orders WHERE Status = '2 shipped' o.ShipDate < DATE '2013-09-01') o WHERE o.CusNo = c.CusNo SELECT CusName FROM Customers c JOIN Orders o ON o.CusNo = c.CusNo WHERE Status = '2 shipped' AND ShipDate < DATE '2013-09-01' wirdvonden meistenDBMS’s unterstützt SELECT CusName FROM Customers JOIN Orders USING(CusNo) WHERE Status = '2 shipped' AND ShipDate < DATE '2013-09-01' SELECT CusName FROM Customers NATURAL JOIN Orders WHERE Status = '2 shipped' AND ShipDate < DATE '2013-09-01' R.Marti InformationssystemefürIngenieure2016 – 3SQL Verwendungvon NATURAL JOIN wirdnichtempfohlen! 51 LeftOuterJoininSQL:1999 AlleInformationenüberalleStudenten(inkl.Programmierkenntnisse): SELECT s.EnrolNo, s.Name, s.FCode, i.IT_Skill FROM Students s LEFT OUTER JOIN IT_Skills i ON i.EnrolNo = s.EnrolNo DieserlinkeäussereVerbund(leftouterjoin)istäquivalentzurfolgendenAnfrage: SELECT s.EnrolNo, s.Name, s.FCode, i.IT_Skill FROM Students s, IT_Skills i WHERE i.EnrolNo = s.EnrolNo UNION ALL -- no duplicate elimination needed => use ALL SELECT s.EnrolNo, s.Name, s.FCode, NULL AS IT_Skill FROM Students s WHERE NOT EXISTS ( SELECT * FROM IT_Skills i WHERE i.EnrolNo = s.EnrolNo ) R.Marti InformationssystemefürIngenieure2016 – 3SQL 52 Aggregatfunktionen:SyntaxundBeispiele InderListederKolonnen(ScalarExpr)ineinerSELECT-Anweisung könnenauchAggregat-funktionen erscheinen,dieausallenWerteneinerTabelle(bzw.allenWerteneinerGruppe, siehespäter) einenAggregatwertberechnet. AggregateFunction = "COUNT(*)" | ( COUNT | SUM | AVG | MIN | MAX ) "(" [ DISTINCT ] ScalarExpr ")" . DasZeichen* inCOUNT(*) bezeichneteinganzesTupel. • AnzahlProdukte,dieangebotenwerden SELECT COUNT(*) FROM Products oder:SELECT COUNT(PrdNo) FROM Products -- PrdNo ist Primärschlüssel oder:SELECT COUNT(Warehouse) FROM Products -- fallsWarehouse keine Nullwerte hat -- COUNT(Column) ergibt dieAnzahl der Tupel,für dieColumn IS NOT NULL gilt • AnzahlOrte,andenenProduktegelagertwerden SELECT COUNT(DISTINCT Warehouse) FROM Products • höchsterRabattallerKunden SELECT MAX(Discount) FROM Customers R.Marti InformationssystemefürIngenieure2016 – 3SQL 53 Aggregatfunktionen(2) • AnzahlKundenmiteinemRabatt,dergrösser als15%(0.15)ist SELECT COUNT(*) FROM Customers WHERE Discount > 0.15 • Kunden,diedenhöchstenRabattallerKunden erhalten SELECT * FROM Customers WHERE Discount = ( SELECT MAX(Discount) FROM Customers ) • Kunden,dieeinenüberdurchschnittlichenRabatt erhalten SELECT * FROM Customers WHERE Discount > ( SELECT AVG(Discount) FROM Customers ) • HöhedesGesamtumsatzes imJahr 2012 SELECT SUM(Qty*Price*(1.0-Discount)) AS YearlyRevenue FROM Orders o JOIN Products p ON p.PrdNo = o.PrdNo JOIN Customers c ON c.CusNo = p.CusNo WHERE OrderDate BETWEEN DATE '2012-01-01' AND DATE '2012-12-31' R.Marti InformationssystemefürIngenieure2016 – 3SQL 54 AggregationmitGruppenbildung:Beispiele OftsollenAggregatwertenichtfüreineganzeTabelleberechnetwerden,sondernfürGruppenvonTupel, dieingewissen(vorgegebenen)KolonnendengleichenWertbesitzen. DieNamendieservorgegebenenKolonnenwerdeninderGROUP BY Klauselspezifiziert. In denColumnSpecs derSELECT Klauseldürfendannnurfolgende Kolonnenstehen: • – Kolonnen,dieinGROUP BY vorkommen(evt.alsArgumentevonOperatoren/Funktionen) – Kolonnen,diealsArgumentevonAggregatsfunktionenvorkommen NummernderProdukteundderenGesamtverkaufszahlseit1.Januar 2013. SELECT FROM WHERE GROUP • PrdNo, SUM(Qty) AS TotalQty Orders OrderDate >= DATE '2013-01-01' BY PrdNo NummerundNamederStudentenmitderAnzahlderihnenbekanntenProgrammiersprachen. SELECT s.EnrolNo, s.Name, COUNT(i.IT_Skill) FROM Students s JOIN IT_Skills i ON i.EnrolNo = s.EnrolNo GROUP BY s.EnrolNo, s.Name R.Marti InformationssystemefürIngenieure2016 – 3SQL 55 AggregationmitGruppenbildung:Auswertung IT_Skills KonzeptionellesAuswertungsmodell(Beispiel): EnrolNo IT_Skill NamederProgrammierspracheund AnzahlderStudenten,diediese Sprachekennen ‘87–604–I’ ‘Java’ ‘87–604–I’ ‘C’ ‘87–604–I’ ‘SQL’ SELECT COUNT(EnrolNo) AS StudCount, IT_Skill FROM IT_Skills GROUP BY IT_Skill ‘91–872–I’ ‘Pascal’ ‘91–872–I’ ‘Java’ ‘91–109–I’ ‘Java’ 1SortierenachGruppierungskolonne(n) 2BildeGruppen 3AggregiereinnerhalbderGruppen StudCount R.Marti 1 IT_Skill 3 EnrolNo IT_Skill ‘87–604–I’ ‘C’ ‘87–604–I’ ‘Java’ ‘91–872–I’ ‘Java’ 1 ‘C’ 3 ‘Java’ ‘91–109–I’ ‘Java’ 1 ‘Pascal’ ‘91–872–I’ ‘Pascal’ 1 ‘SQL’ ‘87–604–I’ ‘SQL’ InformationssystemefürIngenieure2016 – 3SQL 2 56 AggregationmitGruppenbildung:Beispiele FürganzeGruppenkönnenmitHilfederHAVING Klausel zusätzlicheBedingungengestelltwerden. • NummernderProdukteundderenGesamtverkaufszahlab1.Januar 2013, sofern diese Gesamtverkaufszahl grösser als 1000ist. SELECT FROM WHERE GROUP HAVING • PrdNo, SUM(Qty) AS TotalQty Orders OrderDate >= DATE '2013-01-01' BY PrdNo SUM(Qty) > 1000 NamenderStädtemitdemdurchschnittlichenRabattderKundenderStadt, soferndieAnzahldieserKundengrösser als10ist, wobeidasResultatabsteigendgemäss durchschnittlichenRabattengeordnetseinsoll. SELECT FROM GROUP HAVING ORDER R.Marti CusCity, AVG(Discount) Customers BY CusCity COUNT(*) > 10 BY 2 DESC -- Alternative: ORDER BY AVG(Discount) DESC InformationssystemefürIngenieure2016 – 3SQL 57 KonzeptionellesModellfürdieAuswertungvonSQL SELECT DISTINCT ScalarExpressions, AggregationFunctions FROM Tables WHERE FilterCondition GROUP BY Columns HAVING GroupFilterCondition UNION ALL OtherSubqueries ORDER BY 1. BerechnedasKreuzproduktderTabellen inder FROM-Klausel. 2. Eliminiere Zeilen,welchedieFilterCondition derWHERE-Klauselnicht erfüllen (inkl.ON BedingungenbeiVerwendungderJOIN Syntax). 3. GruppieredieverbleibendenZeilengemässGROUP-BY-Klausel ... 4. ...undevaluiere AggregationFunctions umproGruppe1Tupelzu produzieren. 5. Eliminiere Zeilen,dieGruppenrepräsentieren, welchedie GroupFilterCondition derHAVING-Klauselnichterfüllen. 6. Evaluiere ScalarExpressions inderSELECT-Klausel. 7. WendedieMengenoperatoren (UNION,INTERSECT,EXCEPT)aufdie verbleibendenZeilensowieResultate derOtherSubqueries an. 8. Sortiere dieTeilegemäss ORDER-BY-Klausel andeliminiere Duplikate falls DISTINCT spezifiziertwurde (oderdieMengenoperatorenohneALL spezifiziertwurden.) Columns R.Marti InformationssystemefürIngenieure2016 – 3SQL 58