Upload
malin-johansson
View
194
Download
2
Embed Size (px)
Citation preview
10 Facit
SQL frågor del 1
1. Lista hela innehållet i tabellen EMPLOYEES
SELECT * FROM employees;
Kommentar:Det är ok att använda * när man skriver ad hoc frågor. När man programmerar så ska man alltid ange kolumnnamnen specifikt. Det händer att kolumner byter ordning. Det är dessutom svårare att ta bort kolumner som inte används då det inte syns i SQL-satsen.
2. Hur många tecken får du spara kolumnen STREET_ADDRESS i tabellen LOCATIONS? DESC locations;
Ger resultatet:
COLUMN_NAME NULLABLE
DATA_TYPE
DATA_LENGTH
DATA_PRECISION
DATA_SCALE
LOCATION_ID N NUMBER 4 4 0STREET_ADDRESS Y VARCHAR2 40POSTAL_CODE Y VARCHAR2 12CITY N VARCHAR2 30STATE_PROVINCE Y VARCHAR2 25COUNTRY_ID Y CHAR 2
Värdet i data_length för street_address är 40.
Kommentar:DESC är en förkortning av DESCRIBE vilket också fungerar.
3. Gör en projektion: Lista efternamn (LAST_NAME), lön (SALARY) och avdelningsnummer (DEPARTMENT_ID) från tabellen EMPLOYEES.
SELECT last_name, salary, department_id FROM employees;
4 Gör en restriktion. Visa all information för alla anställda som heter John i förnamn.
SELECT * FROM employees WHERE first_name ='John';
ResultatEMPLOYEE_ID
FIRST_NAME
LAST_NAME
EMAIL PHONE_NUMBER
HIRE_DATE
JOB_ID
110 John Chen JCHEN 515.124.4269 1997-09-28 FI_ACCOUNT139 John Seo JSEO 650.121.2019 1998-02-12 ST_CLERK145 John Russell JRUSSEL 011.44.1344.429
2681996-10-01 SA_MAN
Kommentar:Alla kolumner visas inte.
5 Lista JOB_TITLE, MIN_SALARY, MAX_SALARY för alla jobb som minst har MIN_SALARY på 7000. Sätt följande kolumnalias: Jobb titel, Max lön samt Min lön.
SELECT job_title AS "Jobb titel", max_salary "Max lön", min_salary AS"Min lön"
FROM jobs WHERE min_salary >= 7000;
ResultatJobb titel Max lön Min lönPresident 40000 20000Administration Vice President 30000 15000Finance Manager 16000 8200Accounting Manager 16000 8200Sales Manager 20000 10000Purchasing Manager 15000 8000Marketing Manager 15000 9000
Kommentar:Om aliaset har ett mellanslag i sig så måste det skrivas inom ””. AS behöver inte skrivas ut.
6 Visa alla uppgifter om de anställda på avdelning 10 och 20.
SELECT * FROM employees WHERE department_id IN (10, 20);
7 Visa all information om anställda vars efternamn börjar på Ka
SELECT * FROM employees WHERE last_name like 'Ka%'
EMPLOYEE_ID
FIRST_NAME
LAST_NAME
EMAIL PHONE_NUMBER
HIRE_DATE
JOB_ID SALARY
122 Payam Kaufling PKAUFLIN 650.123.3234 1995-05-01
ST_MAN 7900
Alla kolumner visas inte.
8 Visa alla anställa som har en lön mellan 7700 och 11200
SELECT first_name, last_name, salary
FROM employees WHERE salary BETWEEN 7700 AND 11200
Eller
SELECT first_name, last_name, salary
FROM employees WHERE salary >= 7700 AND salary <= 11200
FIRST_NAME
LAST_NAME
SALARY
Alexander Hunold 9000Daniel Faviet 9000John Chen 8200Ismael Sciarra 7700Jose Manuel Urman 7800Den Raphaely 11000Matthew Weiss 8000Adam Fripp 8200Payam Kaufling 7900Gerald Cambrault 11000Eleni Zlotkey 10500Peter Tucker 10000David Bernstein 9500
Alla 29 rader visas inte.
Kommentar:
Det är valfritt att använda båda varianterna. Databashanteraren skriver om BETWEEN … AND … varianten till >= <= så det är samma uttryck om körs.
9 Som ovan men visa enbart de personer som inte får bonus.
SELECT first_name, last_name, salary, commission_pct
FROM employees WHERE salary >= 7700 AND salary <= 11200 AND commission_pct IS NULL
ResultatFIRST_NAME
LAST_NAME
SALARY
COMMISSION_PCT
Alexander Hunold 9000Daniel Faviet 9000John Chen 8200Ismael Sciarra 7700Jose Manuel Urman 7800Den Raphaely 11000Matthew Weiss 8000Adam Fripp 8200Payam Kaufling 7900Hermann Baer 10000William Gietz 8300
10 Visa alla personer som har ett efternamn som slutar på s och ett förnamn som börjar på S.
SELECT first_name, last_name
FROM employees WHERE last_name LIKE '%s' AND first_name LIKE 'S%'
FIRST_NAME
LAST_NAME
Sigal TobiasStephen StilesSusan MarvisShelley Higgens
11 Samma som ovan men visa även de personer som har r som andra bokstav i förnamnet samt ett efternamn som slutar på t. Båda villkoren ska vara uppfyllda.
SELECT first_name, last_name
FROM employees WHERE (last_name like '%s' AND first_name like 'S%') OR (first_name like '_r%' AND last_name like '%t')
FIRST_NAME
LAST_NAME
Bruce ErnstSigal TobiasStephen StilesBritney EverettSusan MarvisShelley Higgens
12 Som ovan men endast alla som har ett JOB_ID som avslutas med CLERK
SELECT first_name, last_name, job_id
FROM employees WHERE ((last_name like '%s' AND first_name like 'S%') OR (first_name like '_r%' AND last_name like '%t')) AND job_id like '%CLERK'
ResultatFIRST_NAME
LAST_NAME
JOB_ID
Sigal Tobias PU_CLERK
Stephen Stiles ST_CLERKBritney Everett SH_CLER
K
13 Vilka personer anställdes före 1993-01-01
SELECT first_name, last_name, hire_date
FROM employees WHERE hire_Date < '1993-01-01'
ResultatFIRST_NAME
LAST_NAME
HIRE_DATE
Steven King 1987-06-17Neena Kochhar 1989-09-21Alexander Hunold 1990-01-03Bruce Ernst 1991-05-21Jennifer Whalen 1987-09-17
14 Visa alla anställa som anställdes mellan dagens datum och 1996-11-29
Frågan tolkas på olika sätt. Här är ett svar.
SELECT first_name, last_name, hire_date
FROM employees WHERE hire_Date >'1996-11-29'
15 Visa tabellnamn och kolumnnamn för alla kolumner som du inte får lägga in NULL
Här gäller det att hitta rätt i data dictionary.
SELECT table_name, column_name, nullable FROM user_tab_columns WHERE nullable = 'N'
TABLE_NAME COLUMN_NAME NULLABLECOUNTRIES COUNTRY_ID NDEPARTMENTS DEPARTMENT_ID NDEPARTMENTS DEPARTMENT_NAM
EN
EMPLOYEES EMPLOYEE_ID NEMPLOYEES LAST_NAME NEMPLOYEES EMAIL NEMPLOYEES HIRE_DATE NEMPLOYEES JOB_ID NEMPLOYEES SALARY NEMP_DETAILS_VIEW EMPLOYEE_ID NEMP_DETAILS_VIEW JOB_ID NEMP_DETAILS_VIEW LAST_NAME NEMP_DETAILS_VIEW SALARY NEMP_DETAILS_VIEW DEPARTMENT_NAM
EN
EMP_DETAILS_VIEW JOB_TITLE NEMP_DETAILS_VIEW CITY NJOBS JOB_ID NJOBS JOB_TITLE NJOB_HISTORY EMPLOYEE_ID NJOB_HISTORY START_DATE NJOB_HISTORY END_DATE NJOB_HISTORY JOB_ID NLOCATIONS LOCATION_ID NLOCATIONS CITY NLOCATIONS_CHECK_VIEW
LOCATION_ID N
LOCATIONS_CHECK_VIEW
CITY N
LOCATIONS_SET1 LOCATION_ID NLOCATIONS_SET1 CITY NLOCATIONS_SET2 LOCATION_ID NLOCATIONS_SET2 CITY N
16. Visa all information om anställda sorterat stigande på efternamn och fallande på anställningsdag.
SELECT last_name, hire_date FROM employees ORDER BY last_name, hire_date DESC;
17. Sortera alla anställda fallande på efternamn. Lägg sedan till WHERE rownum <=10. Vilka poster visas egentligen?
SELECT * FROM employees WHERE rownum <= 10 ORDER BY last_name DESC;
18. Vilka index äger du? Lista enbart indexnamnet.
DESC user_indexes;
SELECT index_name FROM user_indexes ORDER BY index_name;
19. Lista alla index som används i tabellen employees
SELECT index_name FROM user_indexes WHERE table_name = 'EMPLOYEES' ORDER BY index_name;
20. Visa förnamn och efternamn på alla personer som ligger före ’Kaufling’ i bokstavsordning. Sortera på efternamn.
SELECT first_name, last_name FROM employees WHERE last_name < 'Kaufling' ORDER BY last_name;
21. Lista tabellnamn och tabellkommentar för alla tabeller du äger.
SELECT table_name, comments FROM user_tab_comments ORDER BY table_name;
22. Lista alla kolumner i Departments med kolumnkommentarer.
DESC user_col_comments;
SELECT column_name, comments FROM user_col_comments WHERE table_name = 'DEPARTMENTS' ORDER BY column_name;
24. Räkna ut följande uttryck: 2000*345 +200. Du kan använda en tabell som heter DUAL.
SELECT 2000 * 345 + 200 FROM DUAL;
Funktioner
1. Lista, i ordning efter avdelningsnummer, alla anställdas för- och efternamn samt lön ökad med 15 %. Ta bort eventuella decimaler.
SELECT department_id, first_name, last_name, TRUNC (salary * 1.15) salary
FROM employees ORDER BY department_id;
TRUNC kapar bort eventuella decimaler, ingen avrundning sker. Det finns funktioner som hanterar avrundning (bla ROUND).
2. Visa för- och efternamn samt anställningsdag för alla anställda. Anställningsdagen ska ha följande formatmall: ’Dy Month year’
SELECT first_name, last_name, TO_CHAR (hire_date, 'Dy Month year') AS "Hire Date"
FROM employees;
En Oracle databas sparar alltid datum i sekund precision i date datatypen.
3. Som ovan men förnamnet och efternamnet ska enbart visas med små bokstäver.
SELECT LOWER (first_name), LOWER (last_name), TO_CHAR (hire_date, 'Dy Month year') AS "Hire Date"
FROM employees;
4. Som ovan men den anställdes förnamn och efternamn ska slås ihop och visas i en kolumn med Namn som alias.
SELECT LOWER (first_name) || ' ' || LOWER (last_name) AS namn, TO_CHAR (hire_date, 'Dy Month year') AS "Hire Date" FROM employees
5. Visa förnamn, efternamn och commision_pct för alla anställda. Om commision_pct är NULL ska ’0’ visas.
SELECT first_name, last_name, NVL (commission_pct, 0) AS commission_pct FROM employees;
6. Lista alla anställdas namn, anställningsdatum och anställningstid för alla anställda. Anställningstiden ska avrundas till hela år.
SELECT first_name, last_name, hire_date,ROUND (MONTHS_BETWEEN (SYSDATE, hire_date) / 12) AS "Anställningsår"
FROM employees;
7. Vem har lägst lön?Ni har ännu inte lärt er hur man ska få ut ett svar med en fråga. Ett alternativ är att söka ut den minsta lönen först MIN(salary) och använda svaret i en annan fråga.
Med en subfråga ser svaret ut:SELECT first_name, last_name
FROM employees WHERE salary = (SELECT MIN (salary)
FROM employees)
Först utförs subfrågan om att få ut MIN(salary) svaret används sedan i huvudfrågan.
8. Visa förnamn, efternamn och manager_id för alla anställda. Om manager_id är NULL ska ’Företagets VD’ visas.
SELECT first_name, last_name, NVL (TO_CHAR (manager_id), 'Företagets VD')
FROM employees;
9. Hur många rader innehåller tabellen Departments?
SELECT COUNT (*) FROM departments;
Kommentar:COUNT(*) och COUNT(1) utför exakt samma sökning i databasen. Det är ingen prestandaskillnad.
10. Hur många personer har bonus?
SELECT COUNT (*) FROM employees
WHERE commission_pct IS NOT NULL;
11. Hur många chefer finns det?
SELECT COUNT (DISTINCT (manager_id)) FROM employees;
12. Hur många har en årslön över 100000?
SELECT COUNT (*) FROM employees
WHERE salary * 12 > 100000
Kommentar:Av prestandaskäl ska man faktiskt inte skriva som ovan. Det är dock det normala sättet. Det är betydligt bättre att skriva salary > (1000000/12). Det beror på att om det finns ett index på salary kan databasen inte använda det i det första alternativet.
13. Vilka olika typer av jobb (job_id) finns det?
SELECT DISTINCT (job_id) FROM employees;
eller
SELECT job_id FROM employees GROUP BY job_id;
14. Lista alla typer av jobb (job_id) samt max- och minlön för respektive jobb. Sortera i bokstavsordning efter job_id.
SELECT job_id, MAX (salary) MAX, MIN (salary) MIN FROM employees
GROUP BY job_id;
Kommentar:Alla kolumner som inte har en grupperingsfunktion måste stå med I GROUP BY uttrycket.
15. Lista alla avdelningar där medelinkomsten överstiger 5000. Steven King ska inte räknas med
SELECT department_id, AVG (salary) FROM employees WHERE (first_name != 'Steven' AND last_name != 'King') GROUP BY department_id
HAVING AVG (salary) > 5000
16. Lista alla avdelningar där medelinkomsten överstiger 8000.
SELECT department_id, AVG (salary) FROM employees GROUP BY department_id
HAVING AVG (salary) > 8000
17. Gå igenom hur CASE och DECODE funktionerna fungerar.Lista alla anställdas för och efternamn, lön samt följande:Om lönen är <3000 Ska det stå LågavlönadOm lönen är <10000 Ska det stå MedelavlönadOm lönen är >10000 Ska det stå Högavlönad
Använd både CASE och DECODE.
SELECT last_name, first_name, (CASE WHEN salary < 3000 THEN 'Lågavlönad' WHEN salary < 10000 THEN 'Medelavlönad' ELSE 'Högavlönad' END ) FROM employees;
DECODE kan enbart hantera ’=’ så det går inte att lösa det här problemet (på ett enkelt sätt).
Flera tabeller
1 Lista alla anställdas för- och efternamn samt avdelningsnamn
SELECT first_name, last_name, department_name FROM employees e, departments d WHERE e.department_id = d.department_id;
2 Som föregående men endast de som har en lön över 10000
SELECT first_name, last_name, department_name, salary FROM employees e, departments d WHERE e.department_id = d.department_id AND salary > 10000;
3 Lista alla anställdas för och efternamn, avdelningsnamn men endast de som bor i Seattle, Toronto eller Oxford.
SELECT first_name, last_name, department_name, city FROM employees e, departments d, locations l WHERE e.department_id = d.department_id AND l.location_id = d.location_id AND l.city IN ('Seattle', 'Toronto', 'Oxford');
4 Vilken avdelning jobbar Ismael på?
SELECT first_name, last_name, department_name FROM employees e, departments d WHERE e.department_id = d.department_id AND first_name = 'Ismael';
5 Visa anställdas namn och avdelningsnamn. Alla avdelningar ska vara med. Även de som inte har några anställda.
SELECT first_name, last_name, department_name FROM employees e, departments d WHERE e.department_id(+) = d.department_id
6 Visa alla anställningsnummer, namn och manager_id i tabellen employees.
SELECT employee_id, first_name, last_name, manager_id FROM employees;
7 Som föregående men visa även chefens namn.
SELECT e.employee_id, e.first_name, e.last_name, e.manager_id chefid, (m.first_name || ' ' || m.last_name) AS chef FROM employees e, employees m
WHERE m.employee_id = e.manager_id;
8 Som föregående men visa även alla som inte har någon chef
SELECT e.employee_id, e.first_name, e.last_name, e.manager_id chefid, (m.first_name || ' ' || m.last_name) AS chef FROM employees e, employees m WHERE m.employee_id(+) = e.manager_id ORDER BY chef ASC;
Eller enligt ANSI
SELECT e.employee_id, e.first_name, e.last_name, e.manager_id chefid, (m.first_name || ' ' || m.last_name) AS chef FROM employees e LEFT OUTER JOIN employees m ON m.employee_id = e.manager_idORDER BY chef ASC;
9 Som föregående men ta även med den anställdes lön och chefens lön. Det är enbart de personer som har en högre lön än sin chef som ska visas.
SELECT e.employee_id, e.first_name, e.last_name, e.salary, e.manager_id chefid, (m.first_name || ' ' || m.last_name) AS chef, m.salary FROM employees e LEFT OUTER JOIN employees m ON m.employee_id =e.manager_id WHERE e.salary > m.salary ORDER BY chef ASC;
10 Hur många anställda finns det på respektive avdelning? Visa avdelningsnamnet och antalet. Du ska även visa avdelningar som inte har några anställda. I det fallet ska antalet anställda ska ha värdet 0.
SELECT department_name AS "Avdelning", COUNT (employee_id) AS "Anställda" FROM employees e, departments d WHERE e.department_id(+) = d.department_id GROUP BY department_name ORDER BY "Anställda" DESC;
11 Visa alla anställdas förnamn, efternamn och land de arbetar i.
SELECT first_name, last_name, country_name FROM employees e, departments d, locations l, countries c WHERE d.department_id = e.department_id AND d.location_id = l.location_id AND l.country_id = c.country_id;
12 Lista förnamn, efternamn, lön, jobb namn, min lön, max lön för alla jobb som minst har 4500 i lön. Använd en natural join.
SELECT first_name, last_name, job_title, max_salary, min_salary, salary
FROM employees NATURAL JOIN jobs WHERE salary >= 4000;
13 Visa department_id för de avdelningar som inte har några anställda. Använd Set operatorer.
SELECT department_id FROM departmentsMINUSSELECT department_id FROM employees;
14 Lista en trädstruktur med förnamn, efternamn, manager_id, job_id samt level. Starta med personen som har job_id= AD_VP
SELECT employee_id, last_name, first_name, job_id, manager_id, LEVEL FROM employees START WITH job_id = 'AD_VP'CONNECT BY PRIOR employee_id = manager_id;
Subfrågor
1 Vilka personer har samma jobb som Bruce Ernst?
SELECT first_name, last_name, job_id FROM employees WHERE job_id = (SELECT job_id FROM employees WHERE first_name = 'Bruce' AND last_name = 'Ernst');
2 Lista namn och lön på alla personer som har lägre lön än Renske Ladwig. Sortera fallande efter lön. SELECT first_name, last_name, salary FROM employees WHERE salary < (SELECT salary FROM employees WHERE first_name = 'Renske'
AND last_name = 'Ladwig') ORDER BY salary DESC;
3 Vem eller vilka har den lägsta lönen? Lista förnamn, efternamn och lön.
SELECT first_name, last_name, salary FROM employees WHERE salary = (SELECT MIN (salary) FROM employees);
4 Som ovan men visa även den som har den högsta lönen.
SELECT first_name, last_name, salary FROM employees WHERE salary = (SELECT MIN (salary) FROM employees) OR salary = (SELECT MAX (salary) FROM employees)
5 Vem har lägst lön i avdelningen Marketing?
SELECT first_name, last_name, salary FROM employees WHERE (salary, department_id) = (SELECT MIN (salary), e.department_id FROM employees e, departments d WHERE d.department_id = e.department_id AND d.department_name = 'Marketing' GROUP BY e.department_id);
6 Vilka anställda tjänar mest på respektive avdelning?
SELECT first_name, last_name, salary FROM employees WHERE (salary, department_id) IN
(SELECT MAX (salary), e.department_id FROM employees e, departments d WHERE d.department_id = e.department_id GROUP BY e.department_id);
7 Vilken är medellönen för alla som inte är ansvarig för en avdelning?
SELECT AVG (salary) FROM employees WHERE (employee_id) NOT IN (SELECT employee_id FROM employees e, departments d WHERE d.manager_id = e.employee_id);
8 Vilket jobb (job_id) har den lägsta medellönen.
SELECT job_id, AVG (salary) FROM employees GROUP BY job_idHAVING AVG (salary) IN (SELECT MIN (AVG (salary)) FROM employees e GROUP BY job_id);
9 Visa alla personer vars lön sämst är 2500 lägre än vad den högst betalda i respektive avdelning får. Du ska även visa den som har högst betalt.
Detta är en korrelerad subfråga. Observera e.department_id i subfrågan.
SELECT department_id, first_name, last_name, salary FROM employees e WHERE salary >= (SELECT MAX (salary) - 2500 FROM employees WHERE department_id = e.department_id)ORDER BY department_id, salary DESC;
10 Lista en trädstruktur med förnamn, efternamn, manager_id samt level. Starta med personen som är chef för IT avdelningen.
SELECT employee_id, last_name, first_name, job_id, manager_id, LEVEL FROM employeesCONNECT BY PRIOR employee_id = manager_idSTART WITH employee_id = (SELECT employee_id FROM departments d1, employees e1 WHERE e1.employee_id = d1.manager_id
AND d1.department_name = 'IT')
Objekt
DROP TABLE FORETAG CASCADE CONSTRAINTS ;
CREATE TABLE FORETAG ( FORETAGSNR NUMBER (10) NOT NULL, NAMN VARCHAR2 (50) NOT NULL, ORGNR VARCHAR2 (30), POSTADRESS VARCHAR2 (40), POSTNR VARCHAR2 (20), ORT VARCHAR2 (30), LAND VARCHAR2 (40), TELEFONNUMMER VARCHAR2 (40), CONSTRAINT FORETAG_PK PRIMARY KEY ( FORETAGSNR ) ) ;
CREATE INDEX FOR_NAMN_I ON FORETAG(NAMN) ;
CREATE INDEX FOR_ORGNR_I ON FORETAG(ORGNR) ;
DROP TABLE UPPDRAG CASCADE CONSTRAINTS ;
CREATE TABLE UPPDRAG ( UPPDRAGSNR NUMBER (10) NOT NULL, UPPFOLJNNG VARCHAR2 (10), STATUS VARCHAR2 (10), STARTDATUM DATE, SLUTDATUM DATE, MAXTIMMAR NUMBER (10,2), FOR_FORETAGSNR NUMBER (10), CONSTRAINT UPP_UPPDRAGSNR_PK PRIMARY KEY ( UPPDRAGSNR ) ) ;
DROP TABLE KONSULTER CASCADE CONSTRAINTS ;
CREATE TABLE KONSULTER ( KONSULTNR NUMBER (10) NOT NULL, PERSONNR VARCHAR2 (10) NOT NULL, FORNAMN VARCHAR2 (20), EFTERNAMN VARCHAR2 (40), KOMPETENSOMRADE VARCHAR2 (20), SLUTAT DATE,
CONSTRAINT KON_KONSULTNR_PK PRIMARY KEY ( PERSONNR ) ) ;