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.