Archiwum: SQL

Liczba dni (kolejnych / roboczych) pomiędzy dwiema datami

18-lut-10

Kolejna notka z dziedziny baz danych.

Dzisiaj chciałbym pokazać w jaki sposób wyliczyć ilość dni (oraz ilość dni roboczych w drugim przykładzie) pomiędzy dwoma datami. Do tego celu posłużymy się naszą tabelką prac.

Struktura DB wraz z przykładowymi danymi dla omawianych zagadnień znajduje się tutaj.

Dla przypomnienia, tak wygląda tabelka, na której przeprowadzimy nasze ćwiczenia:

mysql> select * from prac;
+----+------------+------------+------------+---------+--------+-----------+
| id | nazwisko   | stanowisko | data_zatr  | wyplata | premia | id_dzialu |
+----+------------+------------+------------+---------+--------+-----------+
|  1 | Kowalski   | sprzedawca | 2005-07-13 |    1600 |    300 |        30 |
|  2 | Malinowski | menadżer   | 2005-09-13 |    2489 |      0 |        30 |
|  3 | Grabski    | analityk   | 2006-07-15 |    1458 |      0 |        20 |
|  4 | Bielecki   | księgowy   | 2006-03-12 |    1236 |      0 |        10 |
|  5 | Kurtyka    | dyrektor   | 2006-04-17 |   11369 |      0 |        10 |
|  6 | Dąbkowski  | księgowy   | 2002-04-13 |    1236 |      0 |        10 |
|  7 | Kononowicz | analityk   | 2006-04-11 |    3548 |      0 |        20 |
|  8 | Janczak    | księgowy   | 2002-01-10 |    3699 |      0 |        10 |
|  9 | Kamiński   | sprzedawca | 2007-09-07 |    1365 |    658 |        30 |
| 10 | Czechowski | analityk   | 2009-01-03 |    3547 |      0 |        20 |
| 11 | Duchnowski | sprzedawca | 2007-09-03 |    1687 |    356 |        30 |
| 12 | Różański   | sprzedawca | 2007-09-07 |    1999 |    200 |        30 |
+----+------------+------------+------------+---------+--------+-----------+
12 rows in set (0.00 sec)

1. Jak policzyć ilość kolejnych dni pomiędzy dwoma datami?

Do rozwiązania postawionego problemu przyda nam się wbudowana funkcja datediff(). W jednym zapytaniu pobieramy obie z interesujących nas dat (w tym przypadku daty zatrudnienia Kowalskiego i Malinowskiego) i podstawiamy je do wspomnianej funkcji:

mysql > SELECT ABS(DATEDIFF(kowalski_data,malinowski_data)) AS roznica FROM
(SELECT data_zatr AS kowalski_data FROM prac WHERE nazwisko = 'Kowalski') X,
(SELECT data_zatr AS malinowski_data FROM prac WHERE nazwisko = 'Malinowski') Y;

Wynik działania naszego zapytania:

+---------+
| roznica |
+---------+
|      62 |
+---------+
1 row in set (0.00 sec)

Oczywiście z funkcji ABS() korzystamy po to, aby wynik naszych obliczeń był zawsze dodatni.

2. Jak policzyć ilość roboczych dni pomiędzy dwoma datami? Więcej…

Jak sprawdzić czy dany rok jest rokiem przestępnym?

06-lip-09

Jednym z najprostszych rozwiązań z jakimi się zetknąłem było sprawdzenie ostatniego dnia lutego.

Powyższy problem rozwiązujemy korzystając z tak zbudowanego zapytania:

SELECT
  DAY( LAST_DAY( DATE_ADD( DATE_ADD( DATE_ADD( CURRENT_DATE, INTERVAL - DAYOFYEAR( CURRENT_DATE ) DAY ), INTERVAL 1 DAY ), INTERVAL 1 MONTH ) ) ) AS wynik;

Ale od początku, rozbierzmy to zapytanie na części pierwsze :)

Więcej…

Pobieranie jedynie wybranych kolumn z zadanej tabeli

04-lip-09

Pierwszy tematyczny wpis na rozgrzewkę ;-)

Struktura DB wraz z przykładowymi danymi dla omawianych zagadnień znajduje się tutaj.

Właściwie każdy kto rozpoczyna swoją przygodę z bazami danych w pierwszej kolejności uczy się jak wybierać dane z bazy.

Ogólna i najprostsza postać klauzuli SELECT (służy do pobierania danych) ma postać:

 SELECT * FROM <tabela>;

Sprawdźmy:

mysql> select * from prac;
+----+------------+------------+------------+---------+--------+-----------+
| id | nazwisko   | stanowisko | data_zatr  | wyplata | premia | id_dzialu |
+----+------------+------------+------------+---------+--------+-----------+
|  1 | Kowalski   | sprzedawca | 2005-07-13 |    1600 |    300 |        30 |
|  2 | Malinowski | menadżer   | 2005-09-13 |    2489 |      0 |        30 |
|  3 | Grabski    | analityk   | 2006-07-15 |    1458 |      0 |        20 |
|  4 | Bielecki   | księgowy   | 2006-03-12 |    1236 |      0 |        10 |
|  5 | Kurtyka    | dyrektor   | 2006-04-17 |   11369 |      0 |        10 |
|  6 | Dąbkowski  | księgowy   | 2002-04-13 |    1236 |      0 |        10 |
|  7 | Kononowicz | analityk   | 2006-04-11 |    3548 |      0 |        20 |
|  8 | Janczak    | księgowy   | 2002-01-10 |    3699 |      0 |        10 |
|  9 | Kamiński   | sprzedawca | 2007-09-07 |    1365 |    658 |        30 |
| 10 | Czechowski | analityk   | 2009-01-03 |    3547 |      0 |        20 |
| 11 | Duchnowski | sprzedawca | 2007-09-03 |    1687 |    356 |        30 |
| 12 | Różański   | sprzedawca | 2007-09-07 |    1999 |    200 |        30 |
+----+------------+------------+------------+---------+--------+-----------+
12 rows in set (0.00 sec)

W sytuacji, w której chcemy zapoznać się z zawartością tylko wybranych kolumn modyfikujemy naszą klauzulę SELECT i w miejsce znaku * wymieniamy (oddzielając przecinkiem) nasze kolumny:

mysql> select nazwisko,wyplata,premia from prac;
+------------+---------+--------+
| nazwisko   | wyplata | premia |
+------------+---------+--------+
| Kowalski   |    1600 |    300 |
| Malinowski |    2489 |      0 |
| Grabski    |    1458 |      0 |
| Bielecki   |    1236 |      0 |
| Kurtyka    |   11369 |      0 |
| Dąbkowski  |    1236 |      0 |
| Kononowicz |    3548 |      0 |
| Janczak    |    3699 |      0 |
| Kamiński   |    1365 |    658 |
| Czechowski |    3547 |      0 |
| Duchnowski |    1687 |    356 |
| Różański   |    1999 |    200 |
+------------+---------+--------+
12 rows in set (0.00 sec)

Szkic DB na potrzeby ćwiczeń

04-lip-09

Na potrzeby naszych rozważań potrzebnych będzie nam klika tabel…

1) pracownicy -> prac

CREATE TABLE IF NOT EXISTS `prac` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nazwisko` varchar(50) COLLATE utf8_polish_ci NOT NULL,
  `stanowisko` varchar(50) COLLATE utf8_polish_ci NOT NULL,
  `data_zatr` date NOT NULL,
  `wyplata` float NOT NULL,
  `premia` float DEFAULT NULL,
  `id_dzialu` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=13 ;
INSERT INTO `prac` (`id`, `nazwisko`, `stanowisko`, `data_zatr`, `wyplata`, `premia`, `id_dzialu`) VALUES
(1, 'Kowalski', 'sprzedawca', '2005-07-13', 1600, 300, 30),
(2, 'Malinowski', 'menadżer', '2005-09-13', 2489, NULL, 30),
(3, 'Grabski', 'analityk', '2006-07-15', 1458, NULL, 20),
(4, 'Bielecki', 'księgowy', '2006-03-12', 1236, NULL, 10),
(5, 'Kurtyka', 'dyrektor', '2006-04-17', 11369, NULL, 10),
(6, 'Dąbkowski', 'księgowy', '2002-04-13', 1236, NULL, 10),
(7, 'Kononowicz', 'analityk', '2006-04-11', 3548, NULL0, 20),
(8, 'Janczak', 'księgowy', '2002-01-10', 3699, NULL, 10),
(9, 'Kamiński', 'sprzedawca', '2007-09-07', 1365, 658, 30),
(10, 'Czechowski', 'analityk', '2009-01-03', 3547, NULL, 20),
(11, 'Duchnowski', 'sprzedawca', '2007-09-03', 1687, 356, 30),
(12, 'Różański', 'sprzedawca', '2007-09-07', 1999, 200, 30);

2) oddziały firmy -> dzial

CREATE TABLE IF NOT EXISTS `dzial` (
  `id` int(11) NOT NULL,
  `nazwa` varchar(50) COLLATE utf8_polish_ci NOT NULL,
  `localizacja` varchar(50) COLLATE utf8_polish_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci;
INSERT INTO `dzial` (`id`, `nazwa`, `localizacja`) VALUES
(10, 'księgowość', 'Wrocław'),
(20, 'rozwoju', 'Wałbrzych'),
(30, 'sprzedaży', 'Świdnica'),
(40, 'transport', 'Wałbrzych');

… które wypełnimy przykładowymi danymi.