Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Membandingkan dua rentang tanggal dalam tabel yang sama

Menggunakan IBM Informix Dynamic Server 11.50.FC6, saya dapat menggunakan urutan SQL ini untuk mendapatkan hasil yang Anda butuhkan:

Penyiapan

CREATE TABLE sales
(
    id       INTEGER NOT NULL,
    id_store INTEGER NOT NULL,
    date     DATE NOT NULL,
    total    DECIMAL(10,2) NOT NULL
);

INSERT INTO sales VALUES( 1, 1, '2010-01-01', 500.00);
INSERT INTO sales VALUES( 2, 1, '2010-01-02', 185.00);
INSERT INTO sales VALUES( 3, 1, '2010-01-03', 135.00);
INSERT INTO sales VALUES( 4, 1, '2009-01-01', 165.00);
INSERT INTO sales VALUES( 5, 1, '2009-01-02', 175.00);
INSERT INTO sales VALUES( 6, 5, '2010-01-01', 130.00);
INSERT INTO sales VALUES( 7, 5, '2010-01-02', 135.00);
INSERT INTO sales VALUES( 8, 5, '2010-01-03', 130.00);
INSERT INTO sales VALUES( 9, 6, '2010-01-01', 100.00);
INSERT INTO sales VALUES(10, 6, '2010-01-02',  12.00);
INSERT INTO sales VALUES(11, 6, '2010-01-03',  85.00);
INSERT INTO sales VALUES(12, 6, '2009-01-01', 135.00);
INSERT INTO sales VALUES(13, 6, '2009-01-02', 400.00);
INSERT INTO sales VALUES(14, 6, '2009-01-07',  21.00);
INSERT INTO sales VALUES(15, 6, '2009-01-08',  45.00);
INSERT INTO sales VALUES(16, 8, '2009-01-09', 123.00);
INSERT INTO sales VALUES(17, 8, '2009-01-10', 581.00);

Kueri

SELECT *
  FROM (SELECT s1.id AS s1id,
               NVL(s1.id_store, s2.id_store) AS s1store,
               NVL(s1.date, MDY(MONTH(s2.date), DAY(s2.date),
                                YEAR(s2.date)+1)) AS s1date,
               s1.total AS s1total,
               s2.id AS s2id,
               NVL(s2.id_store, s1.id_store) AS s2store,
               NVL(s2.date, MDY(MONTH(s1.date), DAY(s1.date),
                                YEAR(s1.date)-1)) AS s2date,
               s2.total AS s2total
          FROM sales AS s1 FULL JOIN sales AS s2
            ON s1.id_store = s2.id_store
           AND s1.date BETWEEN '2010-01-01' AND '2010-01-10'
           AND s2.date BETWEEN '2009-01-01' AND '2009-01-10'
           AND DAY(s1.date)   = DAY(s2.date)
           AND MONTH(s1.date) = MONTH(s2.date)
       ) AS s3
 WHERE s1_date BETWEEN '2010-01-01' AND '2010-01-10'
   AND s2_date BETWEEN '2009-01-01' AND '2009-01-10'
 ORDER BY s1_id_store ASC, s1_date ASC;

Hasil

s1id s1store  s1date     s1total  s2id s2store  s2date     s2total
 1       1    2010-01-01  500.00   4       1    2009-01-01  165.00
 2       1    2010-01-02  185.00   5       1    2009-01-02  175.00
 3       1    2010-01-03  135.00           1    2009-01-03             
 6       5    2010-01-01  130.00           5    2009-01-01             
 7       5    2010-01-02  135.00           5    2009-01-02             
 8       5    2010-01-03  130.00           5    2009-01-03             
 9       6    2010-01-01  100.00  12       6    2009-01-01  135.00
10       6    2010-01-02   12.00  13       6    2009-01-02  400.00
11       6    2010-01-03   85.00           6    2009-01-03             
         6    2010-01-07          14       6    2009-01-07   21.00
         6    2010-01-08          15       6    2009-01-08   45.00
         8    2010-01-09          16       8    2009-01-09  123.00
         8    2010-01-10          17       8    2009-01-10  581.00

Penjelasan

Butuh cukup banyak eksperimen untuk mendapatkan 'benar' ini. Informix memiliki fungsi konstruktor DATE MDY() yang mengambil tiga argumen integer:bulan, hari dan tahun (namanya mnemonic). Ini juga memiliki tiga fungsi analisis:DAY(), MONTH() dan YEAR() yang mengembalikan argumen tanggal, bulan dan tahun. Kueri dalam dengan GABUNG LENGKAP memberi Anda hasil dengan nol di sisi kiri dan kanan. Kriteria 5 bagian dalam klausa ON tampaknya diperlukan; jika tidak, kriteria dalam kueri luar harus lebih kompleks dan membingungkan - jika dapat dibuat berfungsi sama sekali. Kemudian kriteria dalam seleksi luar memastikan bahwa data yang dipilih benar. Salah satu keuntungan dari ekspresi NVL() dalam kueri bagian dalam adalah bahwa kolom ID toko sama dan tidak nol dan tidak ada kolom tanggal yang nol, sehingga urutan demi klausa bisa lebih sederhana - pada ID toko dan salah satu kolom tanggal.

Di Informix, juga dimungkinkan untuk mengerjakan ulang ekspresi tanggal sebagai:

NVL(s1.date, s2.date + 1 UNITS YEAR)
NVL(s2.date, s1.date - 1 UNITS YEAR)

Sebenarnya ada beberapa jenis konversi yang terjadi di balik layar dengan notasi itu, tetapi ini memberi Anda hasil yang sama dan perhitungan ekstra mungkin tidak terlalu signifikan.

Ada juga kesalahan dalam menunggu di Informix; Anda tidak dapat menambah atau mengurangi 1 tahun ke atau dari tanggal 29 Februari - karena tidak ada tanggal 29 Februari di tahun berikutnya atau sebelumnya. Anda harus berhati-hati dengan data Anda; jika tidak, Anda dapat membandingkan data untuk 29-02-2008 dengan 28-02-2009 (serta membandingkan data 28-02-2008 dengan 28-02-2009). Ada proses yang disebut 'pembukuan entri ganda', tetapi bukan ini yang dimaksud, dan perhitungan Anda dapat membingungkan jika '29-02-2008 ditambah 1 tahun' adalah 28-02-2009. Informix menghasilkan kesalahan; itu tidak terlalu membantu. Anda mungkin membuat kode prosedur tersimpan, mungkin, untuk mengembalikan NULL untuk 29-02-2008 ditambah 1 tahun karena tidak ada tanggal untuk membandingkan penjualannya.

Anda harus dapat mengadaptasi aritmatika tanggal ke MySQL dengan cukup mudah; sisa kode tidak perlu diubah.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Menduplikasi tabel MySQL, indeks, dan data

  2. Cara menginstal phpMyAdmin di akun hosting terkelola

  3. Bagaimana cara mengonversi nilai datetime MySQL ke google chart api datetime

  4. Emoticon iPhone dimasukkan ke MySQL tetapi menjadi nilai kosong

  5. Mengapa CONCAT () tidak default ke charset default di MySQL?