Versi MySQL
Kode akan berjalan di MySQL 5.5
Latar Belakang
Saya punya tabel seperti yang berikut ini
CREATE TABLE t
( id INT NOT NULL AUTO_INCREMENT
, patient_id INT NOT NULL
, bed_id INT NOT NULL
, ward_id INT NOT NULL
, admitted DATETIME NOT NULL
, discharged DATETIME
, PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
Tabel ini adalah tentang pasien di rumah sakit dan menyimpan tempat tidur di mana setiap pasien menghabiskan beberapa waktu saat dirawat di rumah sakit.
Setiap bangsal dapat memiliki beberapa tempat tidur dan setiap pasien dapat pindah ke ranjang yang berbeda dalam bangsal yang sama.
Objektif
Yang ingin saya lakukan adalah menemukan berapa banyak waktu yang dihabiskan setiap pasien di bangsal tertentu tanpa harus pindah ke bangsal lain. Yaitu saya ingin menemukan total durasi dari waktu yang ia habiskan bersama dalam lingkungan yang sama.
Kasus cobaan
-- Let's assume that ward_id = 1 corresponds to ICU (Intensive Care Unit)
INSERT INTO t
(patient_id, bed_id, ward_id, admitted, discharged)
VALUES
-- Patient 1 is in ICU, changes some beds, then he is moved
-- out of ICU, back in and finally he is out.
(1, 1, 1, '2015-01-06 06:05:00', '2015-01-07 06:04:00'),
(1, 2, 1, '2015-01-07 06:04:00', '2015-01-07 07:08:00'),
(1, 1, 1, '2015-01-07 07:08:00', '2015-01-08 08:11:00'),
(1, 4, 2, '2015-01-08 08:11:00', '2015-01-08 09:11:00'),
(1, 1, 1, '2015-01-08 09:11:00', '2015-01-08 10:11:00'),
(1, 3, 1, '2015-01-08 10:11:00', '2015-01-08 11:11:00'),
(1, 1, 2, '2015-01-08 11:11:00', '2015-01-08 12:11:00'),
-- Patient 2 is out of ICU, he gets inserted in ICU,
-- changes some beds and he is back out
(2, 1, 2, '2015-01-06 06:00:00', '2015-01-07 06:04:00'),
(2, 1, 1, '2015-01-07 06:04:00', '2015-01-07 07:08:00'),
(2, 3, 1, '2015-01-07 07:08:00', '2015-01-08 08:11:00'),
(2, 1, 2, '2015-01-08 08:11:00', '2015-01-08 09:11:00'),
-- Patient 3 is not inserted in ICU
(3, 1, 2, '2015-01-08 08:10:00', '2015-01-09 09:00:00'),
(3, 2, 2, '2015-01-09 09:00:00', '2015-01-10 10:01:00'),
(3, 3, 2, '2015-01-10 10:01:00', '2015-01-11 12:34:00'),
(3, 4, 2, '2015-01-11 12:34:00', NULL),
-- Patient 4 is out of ICU, he gets inserted in ICU without changing any beds
-- and goes back out.
(4, 1, 2, '2015-01-06 06:00:00', '2015-01-07 06:04:00'),
(4, 2, 1, '2015-01-07 06:04:00', '2015-01-07 07:08:00'),
(4, 1, 2, '2015-01-07 07:08:00', '2015-01-08 09:11:00'),
-- Patient 5 is out of ICU, he gets inserted in ICU without changing any beds
-- and he gets dismissed.
(5, 1, 2, '2015-01-06 06:00:00', '2015-01-07 06:04:00'),
(5, 3, 2, '2015-01-07 06:04:00', '2015-01-07 07:08:00'),
(5, 1, 1, '2015-01-07 07:08:00', '2015-01-08 09:11:00'),
-- Patient 6 is inserted in ICU and he is still there
(6, 1, 1, '2015-01-11 12:34:00', NULL);
Dalam tabel sebenarnya, baris tidak berturut-turut tetapi untuk setiap pasien cap waktu keluar dari satu baris == cap waktu penerimaan baris berikutnya.
SQLFiddle
http://sqlfiddle.com/#!2/b5fe5
Hasil yang diharapkan
Saya ingin menulis sesuatu seperti ini:
SELECT pid, ward_id, admitted, discharged
FROM (....)
WHERE ward_id = 1;
(1, 1, '2015-01-06 06:05:00', '2015-01-08 08:11:00'),
(1, 1, '2015-01-08 09:11:00', '2015-01-09 11:11:00'),
(2, 1, '2015-01-07 06:04:00', '2015-01-08 08:11:00'),
(4, 1, '2015-01-07 06:04:00', '2015-01-07 07:08:00'),
(5, 1, '2015-01-07 07:08:00', '2015-01-08 09:11:00'),
(6, 1, '2015-01-11 12:34:00', NULL);
Harap perhatikan bahwa kami tidak dapat mengelompokkan berdasarkan patient_id. Kami harus mengambil catatan terpisah untuk setiap kunjungan ICU.
Untuk lebih jelasnya, jika seorang pasien menghabiskan waktu di ICU, kemudian pindah dari sana dan kemudian kembali ke sana, saya perlu mengambil total waktu yang dihabiskan dalam setiap kunjungan ICU (yaitu dua catatan)
Jawaban:
Kueri 1, diuji dalam SQLFiddle-1
Kueri 2, yang sama dengan 1 tetapi tanpa tabel turunan. Ini mungkin akan memiliki rencana eksekusi yang lebih baik, dengan indeks yang tepat. Uji dalam SQLFiddle-2 :
Kedua pertanyaan mengasumsikan bahwa ada batasan unik
(patient_id, admitted)
. Jika server berjalan dengan pengaturan ANSI yang ketat,bed_id
harus ditambahkan dalamGROUP BY
daftar.sumber
QUERY YANG DIUSULKAN
Saya memuat Anda sampel data ke basis data lokal di laptop saya. Lalu, saya menjalankan kueri
SEGERA DIUSULKAN DIAJARKAN
USULAN QUERY DIJELASKAN
Dalam subquery AA, saya menghitung jumlah detik yang berlalu menggunakan UNIX_TIMESTAMP () dengan mengurangi
UNIX_TIMESTAMP(discharged)
FROMUNIX_TIMESTAMP(admitted)
. Jika pasien masih di tempat tidur (seperti yang ditunjukkan oleh makhluk yang keluarNULL
), saya menetapkan waktu saat ini SEKARANG () . Lalu, saya lakukan pengurangan. Ini akan memberi Anda durasi terkini untuk setiap pasien yang masih di bangsal.Kemudian, saya menjumlahkan jumlah detik dengan
patient_id
. Akhirnya, saya mengambil detik untuk setiap pasien dan menggunakan SEC_TO_TIME () untuk menampilkan jam, menit, dan detik pasien tinggal.COBALAH !!!
sumber
A
danAA
). Saya pikir salah satu dari mereka sudah cukup.