Tagi: alter table

Zadanie 1.

Na potrzeby kolejnych zadań stwórzmy sobie mini-bazę, składającą się z trzech tabel: Pracownicy (dane pracowników), Działy (informacje o działach firmy) i Flota (samochody w firmie).

Dane do stworzenia tabel – poniżej.

Ja stworzyłam je w schemacie HR.

Screen przedstawia dane wynikowe po połączeniu wszystkich trzech tabel:

z1

 

 

Tworzenie tabel


-- najpierw tworzymy tabelę Dzialy:

CREATE TABLE Dzialy (
id_dzialu INTEGER CONSTRAINT id_dzialu_pk PRIMARY KEY,
nazwa_dzialu VARCHAR2(20) NOT NULL,
stanowisko VARCHAR2(30) NOT NULL,
placa_podstawowa INTEGER NOT NULL
);

-- potem tworzymy tabelę Flota:

CREATE TABLE Flota (
id_auta INTEGER CONSTRAINT id_auta_pk PRIMARY KEY,
marka VARCHAR2(20) NOT NULL,
model_auta VARCHAR2(20) NOT NULL,
kolor VARCHAR2(20),
rejestracja VARCHAR2(10)
);

-- teraz czas na Pracowników:

CREATE TABLE Pracownicy (

id_prac INTEGER CONSTRAINT id_prac_pk PRIMARY KEY,
imie VARCHAR2(20) NOT NULL,
nazwisko VARCHAR2(20) NOT NULL,
data_zatrudnienia DATE NOT NULL,
data_urodzenia DATE NOT NULL,
data_zakonczenia DATE,
telefon VARCHAR2(9),
premia INTEGER DEFAULT '0',
id_dzialu INTEGER,
id_auta INTEGER,
CONSTRAINT id_dzialu_fk FOREIGN KEY (id_dzialu) REFERENCES Dzialy(id_dzialu),
CONSTRAINT id_auta_fk FOREIGN KEY (id_auta) REFERENCES Flota(id_auta)
);

-- modyfikujemy Flotę dodając powiązania z tabelą Pracowników:

ALTER TABLE Flota
ADD id_prac INTEGER;

ALTER TABLE Flota
ADD CONSTRAINT id_prac_fk FOREIGN KEY (id_prac) REFERENCES Pracownicy(id_prac);

--...i na koniec wypelniamy wszystkie trzy tabelki danymi:

INSERT ALL
INTO Dzialy(id_dzialu, nazwa_dzialu, stanowisko, placa_podstawowa) VALUES (100, 'Zarząd', 'Prezes', 7000)
INTO Dzialy(id_dzialu, nazwa_dzialu, stanowisko, placa_podstawowa) VALUES(150, 'Zarząd', 'Zastępca Prezesa', 5000)
INTO Dzialy(id_dzialu, nazwa_dzialu, stanowisko, placa_podstawowa) VALUES(200, 'Kadry', 'Glówny Specjalista', 3500)
INTO Dzialy(id_dzialu, nazwa_dzialu, stanowisko, placa_podstawowa) VALUES(250, 'Kadry', 'Mlodszy Specjalista', 2600)
INTO Dzialy(id_dzialu, nazwa_dzialu, stanowisko, placa_podstawowa) VALUES(300, 'Sprzedaż', 'Manager Sprzedaży', 3000)
INTO Dzialy(id_dzialu, nazwa_dzialu, stanowisko, placa_podstawowa) VALUES(350, 'Sprzedaż', 'Handlowiec', 2650)
INTO Dzialy(id_dzialu, nazwa_dzialu, stanowisko, placa_podstawowa) VALUES(400, 'Obsluga', 'Ochrona', 2500)
INTO Dzialy(id_dzialu, nazwa_dzialu, stanowisko, placa_podstawowa) VALUES(450, 'Obsluga', 'Sprzątanie', 2300)
SELECT * FROM dual;

INSERT ALL
INTO Flota(id_auta, marka, model_auta, kolor, rejestracja) VALUES (7, 'Toyota', 'Yaris', 'biay', 'ABC 1258')
INTO Flota(id_auta, marka, model_auta, kolor, rejestracja) VALUES (8, 'Toyota', 'Yaris', 'biay', 'ABC 2423')
INTO Flota(id_auta, marka, model_auta, kolor, rejestracja) VALUES (9, 'Toyota', 'Yaris', 'czarny', 'ABB 3537')
INTO Flota(id_auta, marka, model_auta, kolor, rejestracja) VALUES (10, 'Toyota', 'Auris', 'srebrny', 'ABA 2587')
INTO Flota(id_auta, marka, model_auta, kolor, rejestracja) VALUES (11, 'Suzuki', 'SX4', 'srebrny', 'CBC 3285')
INTO Flota(id_auta, marka, model_auta, kolor, rejestracja) VALUES (12, 'Suzuki', 'SX4', 'czerwony', 'ABA 8327')
SELECT * FROM dual;

INSERT ALL
INTO Pracownicy(id_prac, imie, nazwisko, id_dzialu, id_auta, premia, data_zatrudnienia, data_urodzenia, data_zakonczenia, telefon)
VALUES (1, 'Anna', 'Kowalska', 100, 12, 1600, '2005-10-19', '1975-12-03', null, '776776776')
INTO Pracownicy(id_prac, imie, nazwisko, id_dzialu, id_auta, premia, data_zatrudnienia, data_urodzenia, data_zakonczenia, telefon)
VALUES (2, 'Jaromir', 'Cieśla', 150, 11, 1300, '2005-10-19', '1978-10-05', null, '775775775')
INTO Pracownicy(id_prac, imie, nazwisko, id_dzialu, id_auta, premia, data_zatrudnienia, data_urodzenia, data_zakonczenia, telefon)
VALUES (3, 'Janina', 'Nowak', 200, null, 950, '2005-10-19', '1966-02-15', null, '774774774')
INTO Pracownicy(id_prac, imie, nazwisko, id_dzialu, id_auta, premia, data_zatrudnienia, data_urodzenia, data_zakonczenia, telefon)
VALUES (4, 'Amelia', 'Beryl', 250, null, 600, '2007-06-23', '1987-07-13', null, '773773773')
INTO Pracownicy(id_prac, imie, nazwisko, id_dzialu, id_auta, premia, data_zatrudnienia, data_urodzenia, data_zakonczenia, telefon)
VALUES (5, 'Jacek', 'Onyks', 300, 10, 500, '2005-10-30', '1982-08-09', null, '772772772')
INTO Pracownicy(id_prac, imie, nazwisko, id_dzialu, id_auta, premia, data_zatrudnienia, data_urodzenia, data_zakonczenia, telefon)
VALUES (6, 'Ernest', 'Opal', 350, 7, 500, '2009-05-01', '1976-07-05', null, '771771771')
INTO Pracownicy(id_prac, imie, nazwisko, id_dzialu, id_auta, premia, data_zatrudnienia, data_urodzenia, data_zakonczenia, telefon)
VALUES (7, 'Anna', 'Nowakowska', 350, 8, 400, '2010-06-05', '1985-11-04', null, '770770770')
INTO Pracownicy(id_prac, imie, nazwisko, id_dzialu, id_auta, premia, data_zatrudnienia, data_urodzenia, data_zakonczenia, telefon)
VALUES (8, 'Jan', 'Rębacz', 350, null, 0, '2015-10-01', '1973-05-12', null, '779779779')
INTO Pracownicy(id_prac, imie, nazwisko, id_dzialu, id_auta, premia, data_zatrudnienia, data_urodzenia, data_zakonczenia, telefon)
VALUES (9, 'Roman', 'Kowal', 400, null, 300, '2008-08-01', '1953-07-09', null, '778778778')
INTO Pracownicy(id_prac, imie, nazwisko, id_dzialu, id_auta, premia, data_zatrudnienia, data_urodzenia, data_zakonczenia, telefon)
VALUES (10, 'Stefan', 'Rolnik', 400, null, 350, '2009-09-01', '1966-08-17', null, '778778778')
INTO Pracownicy(id_prac, imie, nazwisko, id_dzialu, id_auta, premia, data_zatrudnienia, data_urodzenia, data_zakonczenia, telefon)
VALUES (11, 'Renata', 'Gąbka', 450, null, 400, '2011-06-15', '1968-09-09', null, '765765765')
SELECT * FROM dual;

[collapse]

 

Zadanie 5.

1. Utwórz tabelę ProductDiscount (ProductID, UnitPrice, Discount). Klucz główny ustaw na ProductID, a pole Discount domyślnie ma wartość 0.

Utwórz również tabelę ArchiwumPD (ProductID, OldDiscount, NewDiscount).

2. Wypełnij tabelę ProductDiscount danymi z tabeli Products (ProductID, UnitPrice).

3. Ustal rabat 9% dla 10 najdroższych produktów, oraz 6% dla kolejnych pięciu. Zarówno nowe jak i stare wartości rabatu wraz z id produktu przenieś do tabeli ArchiwumPD.

4. Dodaj kolumnę NewPrice, która przechowywać będzie cenę produktu po rabacie. Jeśli produkt nie ma przyznanego rabatu, w polu NewPrice widnieć powinno zero.

5. Przywróć wcześniejsze wartości rabatów dla produktów 7-12 (wzgl. ceny).

Baza: Northwind, Tabele: dbo.ProductDiscount, dbo.ArchiwumPD, Kolumny: ProductID, UnitPrice, Discount, NewPrice, OldDiscount, NewDiscount

z5

 

 

 

 

 

 

 

 

Rozwiązanie

1. CREATE TABLE dbo.ProductDiscount (
ProductID INT PRIMARY KEY,
UnitPrice INT NOT NULL,
Discount NUMERIC(4,3) DEFAULT 0
);

CREATE TABLE dbo.ArchiwumPD (
ProductID INT PRIMARY KEY,
OldDiscount NUMERIC(4,3),
NewDiscount NUMERIC(4,3)

);

2. INSERT INTO dbo.ProductDiscount (ProductID, UnitPrice)
SELECT ProductID, UnitPrice
FROM dbo.Products;

3. Dla pierwszych 10:

WITH CTE AS (
SELECT ProductID, UnitPrice, Discount
FROM dbo.ProductDiscount
ORDER BY UnitPrice DESC
OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY
)

UPDATE CTE
SET Discount = 0.09
OUTPUT
deleted.ProductID,
deleted.Discount,
inserted.Discount
INTO dbo.ArchiwumPD(ProductID, OldDiscount, NewDiscount);

I kolejne 5:

WITH CTE AS (
SELECT ProductID, UnitPrice, Discount
FROM dbo.ProductDiscount
ORDER BY UnitPrice DESC
OFFSET 10 ROWS FETCH NEXT 5 ROWS ONLY
)

UPDATE CTE
SET Discount = 0.06
OUTPUT
deleted.ProductID,
deleted.Discount,
inserted.Discount
INTO dbo.ArchiwumPD(ProductID, OldDiscount, NewDiscount);

Lub z wykorzystaniem tabeli pochodnej (analogicznie będzie przy 10 najdroższych produktach):

UPDATE dbo.ProductDiscount
SET Discount = 0.06
OUTPUT
deleted.ProductID,
deleted.Discount,
inserted.Discount
INTO dbo.ArchiwumPD(ProductID, OldDiscount, NewDiscount)
WHERE ProductID IN (SELECT ProductID
FROM dbo.ProductDiscount
ORDER BY UnitPrice DESC
OFFSET 10 ROWS FETCH NEXT 5 ROWS ONLY);

4. ALTER TABLE dbo.ProductDiscount
ADD NewPrice NUMERIC(5,2);

UPDATE dbo.ProductDiscount
SET NewPrice = UnitPrice*(1 - Discount);

UPDATE dbo.ProductDiscount
SET NewPrice = 0
WHERE Discount = 0;

5. WITH CTE AS (
SELECT PD.Discount as Disc, APD.OldDiscount as OldDisc
FROM dbo.ProductDiscount as PD LEFT JOIN dbo.ArchiwumPD as APD
on PD.ProductID = APD.ProductID
ORDER BY UnitPrice DESC
OFFSET 6 ROWS FETCH NEXT 6 ROWS ONLY
)

UPDATE CTE
SET Disc = OldDisc;

I aktualizujemy ceny w kolumnie NewPrice:

UPDATE dbo.ProductDiscount
SET NewPrice = UnitPrice*(1 - Discount);

UPDATE dbo.ProductDiscount
SET NewPrice = 0
WHERE Discount = 0;

[collapse]

Zadanie 4.

1. Skopiuj tabelę dbo.Orders za pomocą SELECT INTO (tworząc tabelę dbo.Ord2).

2. Tabeli dbo.Ord2 przypisz klucz główny na kolumnie OrderID

3. Dodaj kolumnę ShipDelay, w której określimy, czy towar został dostarczony na czas.

4. Wypełnij kolumnę ShipDelay danymi (RequiredDate – ShippedDate)

5. Zmodyfikuj tabelę wstawiając 0 (zero) tam, gdzie nie było opóźnień w dostawie.

6. Sprawdź, czy są klienci którzy dostali towar z opóźnieniem, oraz czy złożyli jeszcze jakieś zamówienia (później).

Baza: Northwind, Tabela: dbo.Orders / Ord2, Kolumny: CustomerID, OrderID, RequiredDate, ShippedDate, ShipDelay, Wynik: klienci, którzy złożyli kolejne zamówienia po otrzymaniu dostawy z opóźnieniem: 33, Klienci, którzy po opóźnionej dostawie nie złożyli już zamówień: 4, Klienci, którzy po pierwszym opóźnieniu złożyli kolejne zamówienie, ale po drugim już nie: 1

Rozwiązanie

1.

USE Northwind;

SELECT *
INTO dbo.Ord2
FROM dbo.Orders;

2.

ALTER TABLE dbo.Ord2
ADD CONSTRAINT OrderID_pk PRIMARY KEY (OrderID);

3.

ALTER TABLE dbo.Ord2
ADD ShipDelay INT;

4.

WITH CTE AS (
SELECT OrderID, CustomerID, RequiredDate, ShippedDate, ShipDelay, DATEDIFF(day, RequiredDate, ShippedDate) as DaysDelay
FROM dbo.Ord2
)

UPDATE CTE
SET ShipDelay = DaysDelay;

5.

UPDATE dbo.Ord2
SET ShipDelay = 0
WHERE ShipDelay <= 0;

Albo z użyciem wyrażeń tablicowych:

WITH CTE2 AS (
SELECT ShipDelay,
CASE
WHEN ShipDelay <= 0 THEN 0
ELSE ShipDelay
END AS SD

FROM dbo.Ord2
)

UPDATE CTE2
SET ShipDelay = SD;

6. Klienci, którzy złożyli kolejne zamówienia po otrzymaniu dostawy z opóźnieniem:

SELECT CustomerID, OrderID
FROM dbo.Ord2
WHERE ShipDelay > 0
AND EXISTS (
SELECT *
FROM dbo.Ord2 as O
WHERE Ord2.CustomerID = O.CustomerID
AND O.OrderID > Ord2.OrderID
);

 

Klienci, którzy po opóźnionej dostawie nie złożyli już zamówień:

SELECT CustomerID, OrderID
FROM dbo.Ord2
WHERE ShipDelay > 0
AND NOT EXISTS (
SELECT *
FROM dbo.Ord2 as O
WHERE Ord2.CustomerID = O.CustomerID
AND O.OrderID > Ord2.OrderID
);

 

Klienci, którzy po pierwszym opóźnieniu złożyli kolejne zamówienie, ale po drugim już nie:

SELECT CustomerID
FROM dbo.Ord2
WHERE ShipDelay > 0
AND EXISTS (
SELECT *
FROM dbo.Ord2 as O
WHERE Ord2.CustomerID = O.CustomerID
AND O.OrderID > Ord2.OrderID
)

INTERSECT

SELECT CustomerID
FROM dbo.Ord2
WHERE ShipDelay > 0
AND NOT EXISTS (
SELECT *
FROM dbo.Ord2 as O
WHERE Ord2.CustomerID = O.CustomerID
AND O.OrderID > Ord2.OrderID
);

 

[collapse]

Zadanie 3.

1. Utwórz sekwencję (dbo.MySequence) typu INT, o wartości minimalnej 1, z inkrementacją o 1.

2. Utwórz tabelę (dbo.Zabawki) zawierającą kolumny: ID (INT, domyślna wartość to kolejna wartość z sekwencji), KodProduktu (INT, NOT NULL), NazwaProduktu (VARCHAR(20), NOT NULL), Cena (INT, NOT NULL), Kategoria (VARCHAR(15), NOT NULL)

3. Wypełnij tabelę danymi (kod produktu, nazwa, cena, kategoria):

(12064, 'Lego Technic', 565, 'Zabawki'),
(12065, 'Lego City', 129, 'Zabawki'),
(12066, 'Lego City', 155, 'Zabawki'),
(12067, 'Lego Technic', 499, 'Zabawki'),
(12080, 'Need For Speed', 99, 'Gry'),
(12081, 'Tomb Raider', 99, 'Gry'),
(12082, 'The Sims', 159, 'Gry'),
(12083, 'Diablo', 179, 'Gry');

4. Usuń najdroższy produkt z każdej kategorii.

5. Do tabeli dodaj kolumnę Rabat, z wartością domyślną 0.

6. Przyznaj rabat wysokości 15% produktom o kodzie 12082, 12067.

7. Ustaw wartość rabatu na zero wszędzie tam, gdzie ma ma ona wartość NULL.

8. Usuń tabelę dbo.Zabawki oraz sekwencję dbo.MySequence.

Baza: Northwind, Tabela: dbo.Zabawki, Kolumny: ID, KodProduktu, Nazwaproduktu, Cena, Kategoria, Wynik: 6 rows (po modyfikacjach)

Rozwiązanie

1. CREATE SEQUENCE dbo.MySequence AS INT
MINVALUE 1;

–inkrementacja o 1 jest ustawiona domyślnie

2. CREATE TABLE dbo.Zabawki (
ID INT NOT NULL DEFAULT(NEXT VALUE FOR dbo.MySequence),
KodProduktu INT NOT NULL,
NazwaProduktu VARCHAR(20) NOT NULL,
Cena INT NOT NULL,
Kategoria VARCHAR(10) NOT NULL
);

3. INSERT INTO dbo.Zabawki (KodProduktu, NazwaProduktu, Cena, Kategoria)
VALUES
(12064, 'Lego Technic', 565, 'Zabawki'),
(12065, 'Lego City', 129, 'Zabawki'),
(12066, 'Lego City', 155, 'Zabawki'),
(12067, 'Lego Technic', 499, 'Zabawki'),
(12080, 'Need For Speed', 99, 'Gry'),
(12081, 'Tomb Raider', 99, 'Gry'),
(12082, 'The Sims', 159, 'Gry'),
(12083, 'Diablo', 179, 'Gry');

SELECT * FROM dbo.Zabawki;

4. DELETE FROM dbo.Zabawki
WHERE Cena in (
SELECT MAX(Cena)
FROM dbo.Zabawki
GROUP BY Kategoria
);

5. ALTER TABLE dbo.Zabawki
ADD Rabat INT DEFAULT(0);

6. UPDATE dbo.Zabawki
SET Rabat = 15
WHERE KodProduktu in(12082, 12067);

7. UPDATE dbo.Zabawki
SET Rabat = 0
WHERE Rabat IS NULL;

8. DROP TABLE dbo.Zabawki;

DROP SEQUENCE dbo.MySequence;

[collapse]