İki tarih arasındaki tarihlerin listesini alın


91

Standart mysql işlevlerini kullanmak, iki tarih arasındaki günlerin listesini döndürecek bir sorgu yazmanın bir yolu var.

Örneğin, 2009-01-01 ve 2009-01-13 verildiğinde, aşağıdaki değerlere sahip tek sütunlu bir tablo döndürür:

 2009-01-01 
 2009-01-02 
 2009-01-03
 2009-01-04 
 2009-01-05
 2009-01-06
 2009-01-07
 2009-01-08 
 2009-01-09
 2009-01-10
 2009-01-11
 2009-01-12
 2009-01-13

Düzenleme: Görünüşe göre net değildim. Bu listeyi OLUŞTURMAK istiyorum. Veritabanında depolanan değerlerim var (tarih saatine göre) ancak bunların sol dış birleşimde yukarıdaki gibi bir tarih listesine toplanmasını istiyorum (bu birleşimin bazılarının sağ tarafından bazı günler için boş bekliyorum ve bunu halledeceğim ).



Yanıtlar:


68

Bu saklı yordamı, ihtiyacınız olan aralıkları time_intervals adındaki geçici tabloya oluşturmak için kullanırdım , ardından JOIN ve veri tablonuzu temp time_intervals tablosuyla birleştiririm.

Prosedür, içinde belirtilmiş gördüğünüz tüm farklı türlerin aralıklarını oluşturabilir:

call make_intervals('2009-01-01 00:00:00','2009-01-10 00:00:00',1,'DAY')
.
select * from time_intervals  
.
interval_start      interval_end        
------------------- ------------------- 
2009-01-01 00:00:00 2009-01-01 23:59:59 
2009-01-02 00:00:00 2009-01-02 23:59:59 
2009-01-03 00:00:00 2009-01-03 23:59:59 
2009-01-04 00:00:00 2009-01-04 23:59:59 
2009-01-05 00:00:00 2009-01-05 23:59:59 
2009-01-06 00:00:00 2009-01-06 23:59:59 
2009-01-07 00:00:00 2009-01-07 23:59:59 
2009-01-08 00:00:00 2009-01-08 23:59:59 
2009-01-09 00:00:00 2009-01-09 23:59:59 
.
call make_intervals('2009-01-01 00:00:00','2009-01-01 02:00:00',10,'MINUTE')
. 
select * from time_intervals
.  
interval_start      interval_end        
------------------- ------------------- 
2009-01-01 00:00:00 2009-01-01 00:09:59 
2009-01-01 00:10:00 2009-01-01 00:19:59 
2009-01-01 00:20:00 2009-01-01 00:29:59 
2009-01-01 00:30:00 2009-01-01 00:39:59 
2009-01-01 00:40:00 2009-01-01 00:49:59 
2009-01-01 00:50:00 2009-01-01 00:59:59 
2009-01-01 01:00:00 2009-01-01 01:09:59 
2009-01-01 01:10:00 2009-01-01 01:19:59 
2009-01-01 01:20:00 2009-01-01 01:29:59 
2009-01-01 01:30:00 2009-01-01 01:39:59 
2009-01-01 01:40:00 2009-01-01 01:49:59 
2009-01-01 01:50:00 2009-01-01 01:59:59 
.
I specified an interval_start and interval_end so you can aggregate the 
data timestamps with a "between interval_start and interval_end" type of JOIN.
.
Code for the proc:
.
-- drop procedure make_intervals
.
CREATE PROCEDURE make_intervals(startdate timestamp, enddate timestamp, intval integer, unitval varchar(10))
BEGIN
-- *************************************************************************
-- Procedure: make_intervals()
--    Author: Ron Savage
--      Date: 02/03/2009
--
-- Description:
-- This procedure creates a temporary table named time_intervals with the
-- interval_start and interval_end fields specifed from the startdate and
-- enddate arguments, at intervals of intval (unitval) size.
-- *************************************************************************
   declare thisDate timestamp;
   declare nextDate timestamp;
   set thisDate = startdate;

   -- *************************************************************************
   -- Drop / create the temp table
   -- *************************************************************************
   drop temporary table if exists time_intervals;
   create temporary table if not exists time_intervals
      (
      interval_start timestamp,
      interval_end timestamp
      );

   -- *************************************************************************
   -- Loop through the startdate adding each intval interval until enddate
   -- *************************************************************************
   repeat
      select
         case unitval
            when 'MICROSECOND' then timestampadd(MICROSECOND, intval, thisDate)
            when 'SECOND'      then timestampadd(SECOND, intval, thisDate)
            when 'MINUTE'      then timestampadd(MINUTE, intval, thisDate)
            when 'HOUR'        then timestampadd(HOUR, intval, thisDate)
            when 'DAY'         then timestampadd(DAY, intval, thisDate)
            when 'WEEK'        then timestampadd(WEEK, intval, thisDate)
            when 'MONTH'       then timestampadd(MONTH, intval, thisDate)
            when 'QUARTER'     then timestampadd(QUARTER, intval, thisDate)
            when 'YEAR'        then timestampadd(YEAR, intval, thisDate)
         end into nextDate;

      insert into time_intervals select thisDate, timestampadd(MICROSECOND, -1, nextDate);
      set thisDate = nextDate;
   until thisDate >= enddate
   end repeat;

 END;

SQL Server için benzer bir fonksiyon oluşturduğum bu yazının altındaki benzer örnek veri senaryosu .


4
Ben şahsen PostgreSQL'de oluşturulan dizilere benzer bir şey umuyordum.
Phillip Whelan

Verileri bir kez oluşturuyorsanız, kalıcı tablolar kullanabilir ve eksik tarihleri ​​doldurmak için bu komut dosyasını kullanabilirsiniz.
Bimal Poudel

PhpMyAdmin aracılığıyla çalışmasını sağlamak için oluşturma yordamı ifadesinden önce sınırlayıcıyı değiştirmem gerekiyordu (declare deyimlerinde sözdizimi hatasını önlemek için) [code] DECLARE // [/ code]
Defkon1

Bu çözüm çok güçlü ve esnektir, ne yazık ki mariaDB'de # 1067 hatası alıyorum - make_intervals çağrısını çalıştırırken 'interval_end' için geçersiz varsayılan değer ('2009-01-01 00:00:00', '2009-01-10 00: 00: 00 ', 1,' GÜN '); 5.7.28 sürümündeyim
shelbypereira

28

MSSQL için bunu kullanabilirsiniz. ÇOK hızlı.

Bunu tablo değerli bir fonksiyonda toplayabilir veya proc ve başlangıç ​​ve bitiş tarihlerinde değişkenler olarak ayrıştırabilirsiniz.

DECLARE @startDate DATETIME
DECLARE @endDate DATETIME

SET @startDate = '2011-01-01'
SET @endDate = '2011-01-31';

WITH dates(Date) AS 
(
    SELECT @startdate as Date
    UNION ALL
    SELECT DATEADD(d,1,[Date])
    FROM dates 
    WHERE DATE < @enddate
)

SELECT Date
FROM dates
OPTION (MAXRECURSION 0)
GO

2
Burada OPTION (MAXRECURSION 0) kullanımı nedir?
Shiva

14

Veri olmayan o günleri rapor etmek istediğimiz için BIRT raporlarında da benzer bir sorun yaşadık. Bu tarihler için hiçbir giriş olmadığından, bizim için en kolay çözüm, tüm tarihleri ​​saklayan basit bir tablo oluşturmak ve bunu aralıklar elde etmek veya o tarih için sıfır değerleri elde etmek için birleştirmek için kullanmaktı.

Gelecekte 5 yıl boyunca masanın doldurulmasını sağlamak için her ay çalışan bir işimiz var. Tablo şu şekilde oluşturulur:

create table all_dates (
    dt date primary key
);

Şüphesiz, bunu farklı DBMS ile yapmanın sihirli ve zor yolları vardır 'ama biz her zaman en basit çözümü tercih ederiz. Tablo için depolama gereksinimleri minimum düzeydedir ve sorguları çok daha basit ve taşınabilir hale getirir. Bu tür bir çözüm, veriler üzerinde satır başına hesaplamalar gerektirmediğinden, performans açısından neredeyse her zaman daha iyidir.

Diğer seçenek (ve bunu daha önce kullandık) her tarih için tabloda bir giriş olmasını sağlamaktır. Tabloyu periyodik olarak taradık ve var olmayan tarihler ve / veya saatler için sıfır girdi ekledik. Bu sizin durumunuzda bir seçenek olmayabilir, depolanan verilere bağlıdır.

Eğer varsa gerçekten düşünüyorum tutmak için bir güçlük varall_dates nüfuslu masası, bir saklı yordam bu tarihleri içeren bir veri kümesi döndürür hangi gitmek yoludur. Bir tablodan önceden hesaplanmış verileri almak yerine, her çağrıldığında aralığı hesaplamanız gerektiğinden, bu neredeyse kesinlikle daha yavaş olacaktır.

Ancak, dürüst olmak gerekirse, herhangi bir ciddi veri depolama problemi olmadan tabloyu 1000 yıl boyunca doldurabilirsiniz - 365.000 16 baytlık (örneğin) tarih artı tarihi çoğaltan bir dizin artı güvenlik için% 20 ek yük, kabaca tahmin ediyorum yaklaşık 14M [365.000 * 16 * 2 * 1.2 = 14.016.000 bayt]), şeylerin şemasında küçük bir tablo.


12

MySQL'in kullanıcı değişkenlerini şu şekilde kullanabilirsiniz :

SET @num = -1;
SELECT DATE_ADD( '2009-01-01', interval @num := @num+1 day) AS date_sequence, 
your_table.* FROM your_table
WHERE your_table.other_column IS NOT NULL
HAVING DATE_ADD('2009-01-01', interval @num day) <= '2009-01-13'

@num -1'dir çünkü onu ilk kullandığınızda eklersiniz. Ayrıca, "HAVING date_sequence" öğesini kullanamazsınız çünkü bu, kullanıcı değişkeninin her satır için iki kez artmasına neden olur.


8

Bu yanıttan bir fikir alarak 0'dan 9'a kadar bir tablo oluşturabilir ve bunu tarih listenizi oluşturmak için kullanabilirsiniz.

CREATE TABLE num (i int);
INSERT INTO num (i) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);

select adddate('2009-01-01', numlist.id) as `date` from
(SELECT n1.i + n10.i*10 + n100.i*100 AS id
   FROM num n1 cross join num as n10 cross join num as n100) as numlist
where adddate('2009-01-01', numlist.id) <= '2009-01-13';

Bu, 1000 tarihe kadar bir liste oluşturmanıza olanak sağlar. Daha büyük gitmeniz gerekiyorsa, iç sorguya başka bir çapraz birleştirme ekleyebilirsiniz.


Bu çözüm çok daha iyi çalışıyor. Ancak UNIX_TIMESTAMP () ile ilgili bir sorunu var - 1231185600.000000 gibi sonuçlar veriyor; ondalık noktadan sonraki milisaniye bölümü; while - UNIX_TIMESTAMP (ADDDATE ('2009-01-01', 0)) AS'yi SEÇİN date; bu kısımla sonuçlanmaz.
Bimal Poudel

3

Access (veya herhangi bir SQL dili) için

  1. 2 alanı olan bir tablo oluşturun, bu tabloyu adlandıracağız tempRunDates:
    --Fields fromDateve toDate
    --Sonra, başlangıç ​​tarihi ve bitiş tarihi olan yalnızca 1 kayıt ekleyin.

  2. Başka bir tablo oluşturun: - Bu tabloya Time_Day_Ref
    bir tarih listesi aktarın (excel'de liste yapmak kolaydır).
    - Benim durumumdaki alan adı Greg_Dt, Miladi Tarih için
    - Listemi 1 Ocak 2009 ile 1 Ocak 2020 arasında hazırladım.

  3. Sorguyu çalıştırın:

    SELECT Time_Day_Ref.GREG_DT
    FROM tempRunDates, Time_Day_Ref
    WHERE Time_Day_Ref.greg_dt>=tempRunDates.fromDate And greg_dt<=tempRunDates.toDate;
    

Kolay!


2

Tipik olarak, sadece bu amaç için etrafta tuttuğunuz yardımcı numaralar tablosu kullanılır ve bunun üzerinde bazı değişiklikler yapılır:

SELECT *
FROM (
    SELECT DATEADD(d, number - 1, '2009-01-01') AS dt
    FROM Numbers
    WHERE number BETWEEN 1 AND DATEDIFF(d, '2009-01-01', '2009-01-13') + 1
) AS DateRange
LEFT JOIN YourStuff
    ON DateRange.dt = YourStuff.DateColumn

Tablo değerli işlevlerde vb. Varyasyonlar gördüm.

Kalıcı bir tarih listesi de tutabilirsiniz. Bunu veri ambarımızda ve günün saatlerinin bir listesini sunuyoruz.



2
CREATE FUNCTION [dbo].[_DATES]
(
    @startDate DATETIME,
    @endDate DATETIME
)
RETURNS 
@DATES TABLE(
    DATE1 DATETIME
)
AS
BEGIN
    WHILE @startDate <= @endDate
    BEGIN 
        INSERT INTO @DATES (DATE1)
            SELECT @startDate   
    SELECT @startDate = DATEADD(d,1,@startDate) 
    END
RETURN
END

2

MariaDB> = 10.3 ve MySQL> = 8.0'da yeni özyinelemeli (Ortak Tablo İfadeleri) işlevini kullanan zarif çözüm.

WITH RECURSIVE t as (
    select '2019-01-01' as dt
  UNION
    SELECT DATE_ADD(t.dt, INTERVAL 1 DAY) FROM t WHERE DATE_ADD(t.dt, INTERVAL 1 DAY) <= '2019-04-30'
)
select * FROM t;

Yukarıdaki, '2019-01-01' ve '2019-04-30' arasında bir tarih tablosu döndürür.


"'2019-01-01'i dt olarak seçin" bu seçici nedir? Sadece bir alan ve alan seçmek mümkün mü?
Miguel Stevens

1

Bunu İKYS Sistemimizde kullandık, faydalı bulacaksınız

SELECT CAST(DAYNAME(daydate) as CHAR) as dayname,daydate
    FROM
    (select CAST((date_add('20110101', interval H.i*100 + T.i*10 + U.i day) )as DATE) as daydate
      from erp_integers as H
    cross
      join erp_integers as T
    cross
      join erp_integers as U
     where date_add('20110101', interval H.i*100 + T.i*10 + U.i day ) <= '20110228'
    order
        by daydate ASC
        )Days

1

Bu çözüm MySQL 5.0 ile çalışıyor
Tablo oluştur -mytable .
Şema önemli değil. Önemli olan, içindeki satır sayısıdır.
Dolayısıyla, 10 satırlık değerler - 1 ila 10 olan yalnızca bir sütun INT tutabilirsiniz.

SQL:

set @tempDate=date('2011-07-01') - interval 1 day;
select
date(@tempDate := (date(@tempDate) + interval 1 day)) as theDate
from mytable x,mytable y
group by theDate
having theDate <= '2011-07-31';

Sınırlama: Yukarıdaki sorgu tarafından döndürülen maksimum tarih sayısı
(rows in mytable)*(rows in mytable) = 10*10 = 100.

Bu aralığı, sql'deki form parçasını değiştirerek artırabilirsiniz:
mytable x, mytable y, mytable z
Yani, aralık olabilir 10*10*10 =1000vb.


0

A_begin ve a_end olmak üzere iki parametre alan bir saklı yordam oluşturun. İçinde t adında geçici bir tablo oluşturun, d değişkenini bildirin, d'ye a_begin atayın ve a'yı çalıştırınWHILEINSERT ve d'yi t'ye çeviren döngü ve d ADDDATEdeğerini artırmak için işlevi . Nihayet SELECT * FROM t.


Aslında, yürütme hızı için kalıcı bir tablonun daha iyi olacağına inanıyorum (minimum depolama gereksinimleri vardır). Tarihleri ​​bir tabloda önceden hesaplamak ve gerektiğinde çıkarmak, ihtiyaç duyduğunuz her seferinde aralıklar oluşturmaktan daha hızlıdır.
paxdiablo

@Pax, kazanılan hız artışının masa bakımına değip değmeyeceğine bağlıdır. Örneğin, rapor oluşturma 3 saniye sürerse ve tarihleri ​​oluşturmak için WHILE döngüsünü çalıştırmak 0,001 saniye sürerse, performans kazancının göz ardı edilebilir olduğunu iddia ederim. Knuth: Erken optimizasyon tüm kötülüklerin kaynağıdır.
Eugene Yokota

@ eed3si9n, erken optimizasyon, evet, tüm optimizasyon değil :-) Örneğiniz doğruysa, o zaman evet, size katılıyorum, ancak kesinlik için ölçülmelidir. Önerdiğim gibi 1000 yıl sonra (tek seferlik bir maliyet) üretirseniz, masa bakımı sona erdi, ancak bu saniyeler toplanacak.
paxdiablo

0

Buna benzer bir şey kullanırdım:

DECLARE @DATEFROM AS DATETIME
DECLARE @DATETO AS DATETIME
DECLARE @HOLDER TABLE(DATE DATETIME)

SET @DATEFROM = '2010-08-10'
SET @DATETO = '2010-09-11'

INSERT INTO
    @HOLDER
        (DATE)
VALUES
    (@DATEFROM)

WHILE @DATEFROM < @DATETO
BEGIN

    SELECT @DATEFROM = DATEADD(D, 1, @DATEFROM)
    INSERT 
    INTO
        @HOLDER
            (DATE)
    VALUES
        (@DATEFROM)
END

SELECT 
    DATE
FROM
    @HOLDER

Daha sonra @HOLDERDeğişken tablosu, bu iki tarih arasında her gün artan tüm tarihleri ​​kalp içeriğinize katılmaya hazır olarak tutar.


Merhaba, kodu kullanmaya ve çıktıyı DATETIME türünde sütun tarih dolgusu ile DateTest tanımladığım bir tabloya eklemeye çalışıyorum ... ama başarısız ... bununla çalışacak kodu sağlayabilir misiniz lütfen? Not: SQL Server'ı burada kullanmak Teşekkürler :)
sys_debug

0

Bir süredir bununla mücadele ediyorum. Bu, çözümü aradığımda Google'daki ilk isabet olduğundan, şimdiye kadar nerede olduğumu yazmama izin verin.

SET @d := '2011-09-01';
SELECT @d AS d, cast( @d := DATE_ADD( @d , INTERVAL 1 DAY ) AS DATE ) AS new_d
  FROM [yourTable]
  WHERE @d <= '2012-05-01';

[yourTable]Veritabanınızdaki bir tabloyla değiştirin . İşin püf noktası, seçtiğiniz tablodaki satır sayısının> = döndürülmesini istediğiniz tarihlerin sayısı olması gerektiğidir. DUAL tablo yer tutucusunu kullanmayı denedim, ancak yalnızca tek bir satır döndürecekti.


1
İlginç bir yaklaşım. Ama .. bu aslında Vihang'ın yukarıda önerdiği şey değil mi?)?
Leigh

0
select * from table_name where col_Date between '2011/02/25' AND DATEADD(s,-1,DATEADD(d,1,'2011/02/27'))

Burada, önce geçerli bitişTarihine bir gün ekleyin, 2011-02-28 00:00:00 olacak, ardından bitiş tarihini 2011-02-27 23:59:59 yapmak için bir saniye çıkaracaksınız. Bunu yaparak, verilen aralıklar arasındaki tüm tarihleri ​​alabilirsiniz.

çıktı:
2011/02/25
2011/02/26
2011/02/27


0
DELIMITER $$  
CREATE PROCEDURE popula_calendario_controle()
   BEGIN
      DECLARE a INT Default 0;
      DECLARE first_day_of_year DATE;
      set first_day_of_year = CONCAT(DATE_FORMAT(curdate(),'%Y'),'-01-01');
      one_by_one: LOOP
         IF dayofweek(adddate(first_day_of_year,a)) <> 1 THEN
            INSERT INTO calendario.controle VALUES(null,150,adddate(first_day_of_year,a),adddate(first_day_of_year,a),1);
         END IF;
         SET a=a+1;
         IF a=365 THEN
            LEAVE one_by_one;
         END IF;
      END LOOP one_by_one;
END $$

bu prosedür yılın başından bugüne kadar olan tüm tarihleri ​​ekleyecektir, sadece "başlangıç" ve "bitiş" günlerini değiştirin ve gitmeye hazırsınız!


Hat IF a=365 THENartık yıllardan nasıl etkilenir?
Stewart

Ayrıca, 1509. satırdaki sayının anlamı nedir? Bu kod, fazla gerçek açıklaması olmayan bir "pat cevaptır".
Stewart

0

İstatistikler için 2 tarih arasındaki tüm ayları içeren bir listeye ihtiyacım vardı. 2 tarih, aboneliğin başlangıç ​​ve bitiş tarihleridir. Bu yüzden liste tüm ayları ve aylık abonelik miktarını gösterir.

MYSQL

CREATE PROCEDURE `get_amount_subscription_per_month`()
BEGIN
   -- Select the ultimate start and enddate from subscribers
   select @startdate := min(DATE_FORMAT(a.startdate, "%Y-%m-01")), 
          @enddate := max(DATE_FORMAT(a.enddate, "%Y-%m-01")) + interval 1 MONTH
   from subscription a;

   -- Tmp table with all months (dates), you can always format them with DATE_FORMAT) 
   DROP TABLE IF EXISTS tmp_months;
   create temporary table tmp_months (
      year_month date,
      PRIMARY KEY (year_month)
   );


   set @tempDate=@startdate;  #- interval 1 MONTH;

   -- Insert every month in tmp table
   WHILE @tempDate <= @enddate DO
     insert into tmp_months (year_month) values (@tempDate);
     set @tempDate = (date(@tempDate) + interval 1 MONTH);
   END WHILE;

   -- All months
   select year_month from tmp_months;

   -- If you want the amount of subscription per month else leave it out
   select mnd.year_month, sum(subscription.amount) as subscription_amount
   from tmp_months mnd
   LEFT JOIN subscription ON mnd.year_month >= DATE_FORMAT(subscription.startdate, "%Y-%m-01") and mnd.year_month <= DATE_FORMAT(subscription.enddate, "%Y-%m-01")
   GROUP BY mnd.year_month;

 END

0

Bunu kullanabilirsin

SELECT CAST(cal.date_list AS DATE) day_year
FROM (
  SELECT SUBDATE('2019-01-01', INTERVAL 1 YEAR) + INTERVAL xc DAY AS date_list
  FROM (
        SELECT @xi:=@xi+1 as xc from
        (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) xc1,
        (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) xc2,
        (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) xc3,
        (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) xc4,
        (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) xc5,
        (SELECT @xi:=-1) xc0
    ) xxc1
) cal
WHERE cal.date_list BETWEEN '2019-01-01' AND '2019-12-31'
ORDER BY cal.date_list DESC;


-2

Ben kullanıyorum Server version: 5.7.11-log MySQL Community Server (GPL)

Şimdi bunu basit bir şekilde çözeceğiz.

"Datetable" adlı bir tablo oluşturdum

mysql> describe datetable;
+---------+---------+------+-----+---------+-------+
| Field   | Type    | Null | Key | Default | Extra |
+---------+---------+------+-----+---------+-------+
| colid   | int(11) | NO   | PRI | NULL    |       |
| coldate | date    | YES  |     | NULL    |       |
+---------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)

şimdi, içinde eklenen kayıtları göreceğiz.

mysql> select * from datetable;
+-------+------------+
| colid | coldate    |
+-------+------------+
|   101 | 2015-01-01 |
|   102 | 2015-05-01 |
|   103 | 2016-01-01 |
+-------+------------+
3 rows in set (0.00 sec)

ve bu tarihler yerine iki tarih içindeki kayıtları getirme sorgumuz burada.

mysql> select * from datetable where coldate > '2015-01-01' and coldate < '2016-01-01';
+-------+------------+
| colid | coldate    |
+-------+------------+
|   102 | 2015-05-01 |
+-------+------------+
1 row in set (0.00 sec)

umarım bu birçok kişiye yardımcı olur.


Herhangi bir sebep olmaksızın olumsuz oy verildi, bu SQL iyi ve çalışma senaryosunda.
ArifMustafa
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.