giriiş
İlişkisel veritabanları ve Yapılandırılmış Sorgu Dili (SQL) ile çalışırken, belirli tarih veya saatleri temsil eden değerlerle çalışmanız gereken zamanlar olabilir. Örneğin, belirli bir etkinlik için harcanan toplam saati hesaplamanız veya matematiksel operatörler ve işlevler kullanarak tarih veya saat değerlerini toplayıp bunların toplamını veya ortalamasını hesaplamanız gerekebilir.
Bu eğitimde, SQL'de tarih ve saatlerin nasıl kullanılacağını öğreneceksiniz. Sadece SELECT ifadesini kullanarak tarih ve saatlerle ilgili hesaplamalar yapıp çeşitli fonksiyonlar kullanarak başlayacaksınız. Ardından, örnek veriler üzerinde sorgular çalıştırarak pratik yapacak ve çıktıyı daha anlaşılır hale getirmek için CAST fonksiyonunu nasıl uygulayacağınızı öğreneceksiniz.
Ön koşullar
Bu eğitimi tamamlamak için şunlara ihtiyacınız olacak:
- Sudo yönetimsel ayrıcalıklarına sahip, root olmayan bir kullanıcı ve etkin bir güvenlik duvarı bulunan Ubuntu 20.04 çalıştıran bir sunucu.
- Sunucuda MySQL kurulu ve güvenlidir.
Not: Birçok ilişkisel veritabanı yönetim sisteminin kendi benzersiz SQL uygulamalarını kullandığını lütfen unutmayın. Bu eğitimde belirtilen komutlar çoğu İlişkisel Veritabanı Yönetim Sisteminde (RDBMS) çalışsa da, MySQL dışındaki bir sistemde denerseniz tam sözdizimi veya çıktı farklı olabilir.
Bu eğitimde tarih ve saat kullanımında pratik yapmak için, örnek verilerle yüklü bir veritabanı ve tabloya ihtiyacınız olacak. Eklemeye hazır bir veritabanınız yoksa, veritabanı ve tablo oluşturmayı öğrenmek için MySQL'e Bağlanma ve Örnek Veritabanı Oluşturma bölümünü okuyabilirsiniz. Bu eğitimde, bu örnek veritabanı ve tabloya atıfta bulunulacaktır.
MySQL'e bağlanma ve örnek bir veritabanı kurma
SQL veritabanınız uzak bir sunucuda çalışıyorsa, yerel makinenizden sunucunuza SSH ile bağlanın:
ssh sammy@your_server_ip
Daha sonra MySQL komut istemini açın ve Sami'yi MySQL hesap bilgilerinizle değiştirin:
mysql -u sammy -p
datetimeDB adında bir veritabanı oluşturun:
CREATE DATABASE datetimeDB;
Veritabanı başarıyla oluşturulduysa aşağıdaki çıktıyı alacaksınız:
Output
Query OK, 1 row affected (0.01 sec)datetimeDB veritabanını seçmek için aşağıdaki USE ifadesini çalıştırın:
USE datetimeDB;
Output
Database changedVeritabanını seçtikten sonra, içinde bir tablo oluşturun. Bu eğitimde, iki koşucunun bir yıl boyunca koştukları farklı yarışlardaki sonuçlarını içeren bir tablo oluşturacağız. Bu tabloda aşağıdaki yedi sütun bulunmaktadır:
- race_id: int veri tipindeki değerleri temsil eder ve tablonun birincil anahtarı olarak işlev görür, yani bu sütundaki her değer, ilgili satır için benzersiz bir tanımlayıcı görevi görür.
- runner_name: Bolt ve Felix adlı iki koşucunun isimleri için en fazla 30 karakter uzunluğunda varchar veri türünü kullanır.
- race_name: Varchar veri tipine sahip 20 karaktere kadar yarış türlerini tutar.
- start_day: Belirli bir eşleşmenin tarihini yıl, ay ve güne göre izlemek için DATE veri türünü kullanır. Bu veri türü şu parametrelere uyar: yıl için dört basamak ve ay ve gün için en fazla iki basamak (YYYY-AA-GG).
- başlangıç_zamanı: TIME veri türüyle eşleşmenin başlangıç zamanını saat, dakika ve saniye (SS:DD:SS) olarak gösterir. Bu veri türü, 15:00'ın 15:00'e eşdeğer olması gibi 24 saatlik saat biçimini izler.
- toplam_mil: Yarış başına toplam mil sayısının çoğu tam sayı olmadığından, her yarış için toplam mesafeyi ondalık veri türünü kullanarak görüntüler. Bu durumda, ondalık sayı, bir ölçeğinde üç hassasiyeti belirtir; bu da bu sütundaki her değerin üç basamaklı olabileceği ve bu basamaklardan birinin ondalık noktasının sağında olduğu anlamına gelir.
- end_time: Yarış sonunda koşucuların zamanını izlemek için TIMESTAMP veri türünü kullanır. Bu veri türü, tarih ve saati bir dizede birleştirir ve biçimi DATE ve TIME: (YYYY-AA-GG SS:DD:SS) birleşimidir.
CREATE TABLE komutunu çalıştırarak tabloyu oluşturun:
CREATE TABLE race_results (
race_id int,
runner_name varchar(30),
race_name varchar(20),
start_day DATE,
start_time TIME,
total_miles decimal(3, 1),
end_time TIMESTAMP,
PRIMARY KEY (race_id)
); Daha sonra boş tabloya bazı örnek veriler girin:
INSERT INTO race_results
(race_id, runner_name, race_name, start_day, start_time, total_miles, end_time)
VALUES
(1, 'bolt', '1600_meters', '2022-09-18', '7:00:00', 1.0, '2022-09-18 7:06:30'),
(2, 'bolt', '5K', '2022-10-19', '11:00:00', 3.1, '2022-10-19 11:22:31'),
(3, 'bolt', '10K', '2022-11-20', '10:00:00', 6.2, '2022-11-20 10:38:05'),
(4, 'bolt', 'half_marathon', '2022-12-21', '6:00:00', 13.1, '2022-12-21 07:39:04'),
(5, 'bolt', 'full_marathon', '2023-01-22', '8:00:00', 26.2, '2023-01-22 11:23:10'),
(6, 'felix', '1600_meters', '2022-09-18', '7:00:00', 1.0, '2022-09-18 7:07:15'),
(7, 'felix', '5K', '2022-10-19', '11:00:00', 3.1, '2022-10-19 11:30:50'),
(8, 'felix', '10K', '2022-11-20', '10:00:00', 6.2, '2022-11-20 11:10:17'),
(9, 'felix', 'half_marathon', '2022-12-21', '6:00:00', 13.1, '2022-12-21 08:11:57'),
(10, 'felix', 'full_marathon', '2023-01-22', '8:00:00', 26.2, '2023-01-22 12:02:10');Output
Query OK, 10 rows affected (0.00 sec)
Records: 10 Duplicates: 0 Warnings: 0Verilerinizi girdikten sonra SQL'de tarih ve saatlerle aritmetik ve fonksiyon uygulamaları yapmaya başlayabilirsiniz.
Hesabın tarih ve saatle kullanılması
SQL'de tarih ve saat değerlerini matematiksel ifadeler kullanarak işleyebilirsiniz. Tek ihtiyacınız olan bir matematiksel operatör ve hesaplamak istediğiniz değerlerdir.
Örneğin, bir diğerinden belirtilen gün sayısı kadar sonra gelen bir tarihi bulmak istediğinizi varsayalım. Aşağıdaki sorgu, bir tarih değeri (2022-10-05) alır ve sorguda belirtilen tarihten on yedi gün sonrasına ait bir tarih değeri döndürmek için bu değere 17 ekler. Bu örnekte, DBMS'nin bunu bir dize veya başka bir veri türü olarak yorumlamaması için TARİH değeri olarak 2022-10-05 belirtildiğini unutmayın:
SELECT DATE '2022-10-05' + 17 AS new_date;
Output
+----------+
| new_date |
+----------+
| 20221022 |
+----------+
1 row in set (0.01 sec)Bu çıktının gösterdiği gibi, 2022-10-05'ten 17 gün sonra tarih 2022-10-22, yani 22 Ekim 2022'dir.
Başka bir örnek olarak, iki farklı zaman arasındaki toplam saati hesaplamak istediğinizi varsayalım. Bunu, iki zamanı birbirinden çıkararak yapabilirsiniz. Aşağıdaki sorgu için ilk zaman değeri 11:00, ikinci zaman değeri ise 3:00'tür. Saat farkını döndürmek için her iki değerin de TIME değeri olduğunu belirtmeniz gerekir:
SELECT TIME '11:00' - TIME '3:00' AS time_diff;
Output
+-----------+
| time_diff |
+-----------+
| 80000 |
+-----------+
1 row in set (0.00 sec)Bu çıktı size 11:00 ile 3:00 arasındaki farkın 80.000, yani 8 saat olduğunu söyler.
Şimdi örnek verilerden tarih ve saat bilgileri üzerinde hesaplamalar yapma alıştırması yapın. İlk sorgu için, koşucuların her yarışı bitirmelerinin toplam süresini, başlangıç_zamanından bitiş_zamanını çıkararak hesaplayın:
SELECT runner_name, race_name, end_time - start_time
AS total_time
FROM race_results;Output
+-------------+---------------+----------------+
| runner_name | race_name | total_time |
+-------------+---------------+----------------+
| bolt | 1600_meters | 20220918000630 |
| bolt | 5K | 20221019002231 |
| bolt | 10K | 20221120003805 |
| bolt | half_marathon | 20221221013904 |
| bolt | full_marathon | 20230122032310 |
| felix | 1600_meters | 20220918000715 |
| felix | 5K | 20221019003050 |
| felix | 10K | 20221120011017 |
| felix | half_marathon | 20221221021157 |
| felix | full_marathon | 20230122040210 |
+-------------+---------------+----------------+
10 rows in set (0.00 sec)total_time sütunundaki bu çıktının oldukça uzun ve okunması zor olduğunu fark edeceksiniz. Şimdi, bu veri değerlerini daha anlaşılır hale getirmek için CAST fonksiyonunu nasıl kullanacağınızı göstereceğiz.
Şimdi, her koşucunun yalnızca yarı ve tam maraton gibi daha uzun yarışlardaki performansıyla ilgileniyorsanız, bu bilgileri almak için verilerinizi sorgulayabilirsiniz. Bu sorgu için, bitiş_saatini başlangıç_saatinden çıkarın ve sonuçlarınızı, toplam_mil'in 12'den büyük olduğu verileri almak için bir WHERE ifadesi kullanarak sınırlayın:
SELECT runner_name, race_name, end_time - start_time AS half_full_results
FROM race_results
WHERE total_miles > 12;Output
+-------------+---------------+-------------------+
| runner_name | race_name | half_full_results |
+-------------+---------------+-------------------+
| bolt | half_marathon | 20221221013904 |
| bolt | full_marathon | 20230122032310 |
| felix | half_marathon | 20221221021157 |
| felix | full_marathon | 20230122040210 |
+-------------+---------------+-------------------+
4 rows in set (0.00 sec)Bu bölümde, SELECT ifadesiyle ve örnek veriler üzerinde pratik amaçlarla bazı tarih ve saat hesaplamaları gerçekleştirdiniz. Ardından, çeşitli tarih ve saat fonksiyonlarını kullanarak sorgular üzerinde alıştırmalar yapacaksınız.
Tarih ve saat fonksiyonlarını ve aralık ifadelerini kullanma
SQL'de tarih ve saat değerlerini bulmak ve değiştirmek için kullanılabilecek çeşitli işlevler vardır. SQL işlevleri genellikle verileri işlemek veya değiştirmek için kullanılır ve kullanılabilir işlevler SQL uygulamasına bağlıdır. Ancak çoğu SQL uygulaması, current_date ve current_time değerlerini sorgulayarak geçerli tarih ve saati bulmanıza olanak tanır.
Örneğin bugünün tarihini bulmak için sözdizimi kısadır ve yalnızca SELECT ifadesinden ve current_date fonksiyonundan oluşur, şöyle:
SELECT current_date;
Output
+--------------+
| current_date |
+--------------+
| 2022-02-15 |
+--------------+
1 row in set (0.00 sec)Aynı sözdizimini kullanarak, current_time fonksiyonuyla güncel saati bulabilirsiniz:
SELECT current_time;
Output
+--------------+
| current_time |
+--------------+
| 17:10:20 |
+--------------+
1 row in set (0.00 sec)Çıktıda tarih ve saati sorgulamayı tercih ederseniz current_timestamp fonksiyonunu kullanın:
SELECT current_timestamp;
Output
+---------------------+
| current_timestamp |
+---------------------+
| 2022-02-15 19:09:58 |
+---------------------+
1 row in set (0.00 sec)Önceki bölümdekine benzer şekilde, aritmetik fonksiyonlarda bu tür tarih ve saat fonksiyonlarını kullanabilirsiniz. Örneğin, bugünden 11 gün önceki tarihin ne olduğunu öğrenmek istediğinizi varsayalım. Bu durumda, current_date fonksiyonunu sorgulamak için kullandığınız sözdizimini kullanabilir ve ardından on bir gün önceki tarihi bulmak için bu değerden 11 çıkarabilirsiniz:
SELECT current_date - 11;
Output
+-------------------+
| current_date - 11 |
+-------------------+
| 20220206 |
+-------------------+
1 row in set (0.01 sec)Bu çıktıda görüldüğü gibi, current_date'den 11 gün önce (bu makalenin yazıldığı tarihte) tarih 2022-02-06, yani 6 Şubat 2022 idi. Şimdi aynı işlemi deneyin, ancak current_date'i current_time fonksiyonuyla değiştirin:
SELECT current_time - 11;
Output
+-------------------+
| current_time - 11 |
+-------------------+
| 233639 |
+-------------------+
1 row in set (0.00 sec)Bu çıktı, current_time değerinden 11 çıkarıldığında 11 saniye çıkarıldığını gösteriyor. Daha önce current_date işlevini kullanarak gerçekleştirdiğiniz işlem, 11'i saniye olarak değil, gün olarak yorumluyordu. Sayıların yorumlanma biçimindeki bu tutarsızlık, tarih ve saat işlevleriyle çalışırken kafa karıştırıcı olabilir. Tarih ve saat değerlerini bu tür hesaplamalar kullanarak değiştirmenizi gerektirmek yerine, birçok veritabanı yönetim sistemi INTERVAL ifadeleri kullanarak daha açık olmanıza olanak tanır.
INTERVAL ifadeleri, bir tarih veya saat ifadesinden belirli bir zaman aralığından önce veya sonra bir tarih veya saat belirtmenize olanak tanır. Aşağıdaki biçimde olmalıdırlar:
INTERVAL value unit
Örneğin, beş gün sonraki tarihi bulmak için aşağıdaki sorguyu çalıştırabilirsiniz:
SELECT current_date + INTERVAL '5' DAY AS "5_days_from_today";
Bu örnek, current_date değerini bulur ve ardından INTERVAL '5' DAY aralık ifadesini buna ekler. Bu, 5 gün sonraki tarihi döndürür:
Output
+-------------------+
| 5_days_from_today |
+-------------------+
| 2022-03-06 |
+-------------------+
1 row in set (0.00 sec)Bu, benzer, ancak aynı olmayan çıktıyı üreten aşağıdaki sorgudan çok daha az belirsizdir:
SELECT current_date + 5 AS "5_days_from_today";
Output
+-------------------+
| 5_days_from_today |
+-------------------+
| 20220306 |
+-------------------+
1 row in set (0.00 sec)Belirli bir tarih değerinden önceki değerleri bulmak için tarihlerden veya saatlerden zaman aralıklarını çıkarabileceğinizi unutmayın:
SELECT current_date - INTERVAL '7' MONTH AS "7_months_ago";
Output
+--------------+
| 7_months_ago |
+--------------+
| 2021-08-01 |
+--------------+
1 row in set (0.00 sec)INTERVAL ifadelerinde hangi birimlerin kullanılabileceği, seçtiğiniz DBMS'ye bağlıdır; ancak çoğunda SAAT, DAKİKA ve SANİYE gibi seçenekler bulunur:
SELECT current_time + INTERVAL '6' HOUR AS "6_hours_from_now",
current_time - INTERVAL '5' MINUTE AS "5_minutes_ago",
current_time + INTERVAL '20' SECOND AS "20_seconds_from_now";Output
+------------------+---------------+---------------------+
| 6_hours_from_now | 5_minutes_ago | 20_seconds_from_now |
+------------------+---------------+---------------------+
| 07:51:43 | 01:46:43 | 01:52:03.000000 |
+------------------+---------------+---------------------+
1 row in set (0.00 sec)Artık aralık ifadeleri ve bazı tarih ve saat fonksiyonlarını öğrendiğinize göre, ilk adımda girdiğiniz örnek verilerle çalışmaya devam edin.
Tarih ve saatlerle CAST ve Aggregate işlevlerini kullanma
Aritmetiği Tarih ve Saatlerle Kullanma bölümündeki üçüncü örneği hatırlayın. Her koşucunun her yarışta koştuğu toplam saati hesaplamak için bitiş_saatini başlangıç_saatinden çıkarmak üzere aşağıdaki sorguyu çalıştırmıştık. Ancak çıktı, tabloda ayarlanan TIMESTAMP veri türünü izleyen çok uzun bir çıktı içeren bir sütunla sonuçlandı:
SELECT runner_name, race_name, end_time - start_time
AS total_time
FROM race_results;Output
+-------------+---------------+----------------+
| runner_name | race_name | total_time |
+-------------+---------------+----------------+
| bolt | 1600_meters | 20220918000630 |
| bolt | 5K | 20221019002231 |
| bolt | 10K | 20221120003805 |
| bolt | half_marathon | 20221221013904 |
| bolt | full_marathon | 20230122032310 |
| felix | 1600_meters | 20220918000715 |
| felix | 5K | 20221019003050 |
| felix | 10K | 20221120011017 |
| felix | half_marathon | 20221221021157 |
| felix | full_marathon | 20230122040210 |
+-------------+---------------+----------------+
10 rows in set (0.00 sec)Farklı veri türlerine sahip iki sütunda işlem yaptığınız için (end_time TIMESTAMP değerlerini ve start_time TIME değerlerini tutar), veritabanı işlemin sonucunu yazdırırken hangi veri türünü kullanacağını bilemez. Bunun yerine, işlemi gerçekleştirmek için her iki değeri de tam sayılara dönüştürür ve bu da total_time sütununda uzun sayılarla sonuçlanır.
Bu verileri daha anlaşılır ve anlaşılır kılmak için, bu uzun tamsayı değerlerini TIME veri türüne dönüştürmek üzere CAST işlevini kullanabilirsiniz. Bunu yapmak için, CAST ile başlayın ve hemen ardından açık bir parantez, dönüştürmek istediğiniz değerleri ve ardından AS anahtar sözcüğünü ve dönüştürmek istediğiniz veri türünü ekleyin.
Aşağıdaki sorgu önceki örnekle aynıdır, ancak total_time sütununu zaman veri türüne dönüştürmek için bir CAST işlevi kullanır:
SELECT runner_name, race_name, CAST(end_time - start_time AS time)
AS total_time
FROM race_results;Output
+-------------+---------------+------------+
| runner_name | race_name | total_time |
+-------------+---------------+------------+
| bolt | 1600_meters | 00:06:30 |
| bolt | 5K | 00:22:31 |
| bolt | 10K | 00:38:05 |
| bolt | half_marathon | 01:39:04 |
| bolt | full_marathon | 03:23:10 |
| felix | 1600_meters | 00:07:15 |
| felix | 5K | 00:30:50 |
| felix | 10K | 01:10:17 |
| felix | half_marathon | 02:11:57 |
| felix | full_marathon | 04:02:10 |
+-------------+---------------+------------+
10 rows in set (0.00 sec)CAST, bu çıktıdaki veri değerlerini TIME'a dönüştürdü ve bu sayede okunması ve anlaşılması çok kolay hale geldi.
Şimdi, her koşucunun sonuçlarının en kısa, en uzun ve toplam süresini bulmak için CAST işleviyle birlikte bazı toplama işlevlerini kullanalım. İlk olarak, MIN işleviyle harcanan minimum (veya en kısa) süreyi arayın. Yine, netlik sağlamak için TIMESTAMP veri değerlerini TIME veri değerlerine dönüştürmek için CAST işlevini kullanabilirsiniz. Bu örnekteki gibi iki işlev kullanırken iki parantez kullanılması gerektiğini ve toplam saat hesaplamasının (bitiş_saati - başlangıç_saati) bunlardan birine yerleştirilmesi gerektiğini lütfen unutmayın. Son olarak, koşucunun yarış sonuçları çıktısını görüntülemek için bu değerleri runner_name sütununa göre düzenlemek üzere bir GROUP BY ifadesi ekleyin:
SELECT runner_name, MIN(CAST(end_time - start_time AS time)) AS min_time
FROM race_results GROUP BY runner_name;Output
+-------------+----------+
| runner_name | min_time |
+-------------+----------+
| bolt | 00:06:30 |
| felix | 00:07:15 |
+-------------+----------+
2 rows in set (0.00 sec)Bu çıktı koşucunun en kısa süresini gösteriyor, bu durumda Bolt için en az altı dakika 30 saniye, Felix için ise yedi dakika 15 saniye.
Ardından, her çalıştırıcı için en uzun yürütme süresini bulun. Önceki ifadeyle aynı sözdizimini kullanabilirsiniz, ancak bu sefer MIN yerine MAX kullanın:
SELECT runner_name, MAX(CAST(end_time - start_time AS time)) AS max_time
FROM race_results GROUP BY runner_name;Output
+-------------+----------+
| runner_name | max_time |
+-------------+----------+
| bolt | 03:23:10 |
| felix | 04:02:10 |
+-------------+----------+
2 rows in set (0.00 sec)Bu çıktı bize Bolt'un en uzun koşu süresinin toplamda üç saat 23 dakika 10 saniye olduğunu gösteriyor. Felix'in ise toplamda dört saat 2 dakika 10 saniye olduğunu.
Şimdi, her koşucunun toplam kaç saat koştuğuna dair üst düzey bilgileri sorgulayalım. Bu sorgu için, SUM işlevini kullanarak bitiş_saati - başlangıç_saati temelinde toplam saatleri bulun ve bu veri değerlerini TIME'a dönüştürmek için CAST kullanın. Her koşucunun sonuç değerlerini düzenlemek için GROUP BY eklemeyi unutmayın:
SELECT runner_name, SUM(CAST(end_time - start_time AS time))
AS total_hours FROM race_results GROUP BY runner_name;Output
+-------------+-------------+
| runner_name | total_hours |
+-------------+-------------+
| bolt | 52880 |
| felix | 76149 |
+-------------+-------------+
2 rows in set (0.00 sec)İlginçtir ki, bu çıktı MySQL'in toplam süreyi tam sayı olarak yorumladığını gösteriyor. Bu sonuçları zaman olarak okursak, Bolt'un toplam süresi beş saat, 28 dakika ve 80 saniyeye bölünür. Felix'in süresi ise yedi saat, 61 dakika ve 49 saniyeye bölünür. Gördüğünüz gibi, bu mantıksal bir zaman dağılımı değil, bir zaman olarak değil, tam sayı olarak hesaplandığını gösteriyor. Örneğin, bunu PostgreSQL gibi farklı bir DBMS'de denerseniz, aynı sorgu biraz farklı görünecektir:
SELECT runner_name, SUM(CAST(end_time - start_time AS time))
AS total_hours FROM race_results GROUP BY runner_name;Output
runner_name | total_hours
-------------+-------------
felix | 10:01:44
bolt | 06:09:20
(2 rows)Bu durumda, PostgreSQL'deki sorgu, değerleri zaman olarak yorumlar ve hesaplar, böylece Felix'in sonuçları toplamda 10 saat, bir dakika ve 44 saniyeye, Bolt'un sonuçları ise altı saat, dokuz dakika ve 20 saniyeye düşer. Bu, farklı DBMS uygulamalarının, aynı sorguyu ve veri kümesini kullansalar bile veri değerlerini nasıl farklı yorumlayabileceğinin bir örneğidir.
Sonuç
SQL'de tarih ve saatlerin nasıl kullanılacağını anlamak, dakika, saniye, saat, gün, ay, yıl gibi belirli sonuçları ararken veya bunların bir kombinasyonunu ararken faydalıdır. Ayrıca, geçerli tarih veya saat gibi belirli değerleri bulmayı kolaylaştıran birçok tarih ve saat işlevi vardır. Bu eğitim yalnızca SQL'de tarih ve saatlerle ilgili toplama ve çıkarma işlemlerini ele alsa da, tarih ve saat değerlerini herhangi bir matematiksel ifadeyle kullanabilirsiniz. Matematiksel ifadeler ve toplama işlevleri kılavuzumuzdan daha fazla bilgi edinin ve bunları tarih ve saat aramalarınızda deneyin.









