MySQL-Version
Der Code wird in MySQL 5.5 ausgeführt
Hintergrund
Ich habe eine Tabelle wie die folgende
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;
Diese Tabelle handelt von Patienten in einem Krankenhaus und speichert die Betten, in denen jeder Patient einige Zeit im Krankenhaus verbracht hat.
Jede Station kann mehrere Betten haben und jeder Patient kann in ein anderes Bett innerhalb derselben Station umziehen.
Zielsetzung
Ich möchte herausfinden, wie viel Zeit jeder Patient auf einer bestimmten Station verbracht hat, ohne auf eine andere Station gezogen zu sein. Das heißt, ich möchte die Gesamtdauer der aufeinanderfolgenden Zeit ermitteln, die er auf derselben Station verbracht hat.
Testfall
-- 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);
In der realen Tabelle sind die Zeilen nicht aufeinanderfolgend, sondern für jeden Patienten der Entlassungszeitstempel aus einer Zeile == der Aufnahmezeitstempel der nächsten Zeile.
SQLFiddle
http://sqlfiddle.com/#!2/b5fe5
erwartetes Ergebnis
Ich möchte so etwas wie das Folgende schreiben:
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);
Bitte beachten Sie, dass wir nicht nach patient_id gruppieren können. Wir müssen für jeden Intensivbesuch einen separaten Datensatz abrufen.
Um es klarer auszudrücken: Wenn ein Patient Zeit auf der Intensivstation verbringt, dann aus der Intensivstation auszieht und dann dorthin zurückkehrt, muss ich die Gesamtzeit abrufen, die er bei jedem Besuch auf der Intensivstation verbracht hat (dh zwei Aufzeichnungen).
Antworten:
Abfrage 1, getestet in SQLFiddle-1
Abfrage 2, die mit 1 identisch ist, jedoch keine abgeleiteten Tabellen enthält. Dies wird wahrscheinlich einen besseren Ausführungsplan mit geeigneten Indizes haben. Test in SQLFiddle-2 :
Bei beiden Abfragen wird davon ausgegangen, dass eine eindeutige Einschränkung besteht
(patient_id, admitted)
. Wenn der Server mit strengen ANSI-Einstellungen ausgeführt wird,bed_id
sollte dies in dieGROUP BY
Liste aufgenommen werden.quelle
Vorgeschlagene Abfrage
Ich habe Ihre Beispieldaten in eine lokale Datenbank auf meinem Laptop geladen. Dann habe ich die Abfrage ausgeführt
Vorgeschlagene Abfrage ausgeführt
Vorgeschlagene Anfrage erklärt
In der Unterabfrage AA berechne ich die Anzahl der Sekunden, die mit UNIX_TIMESTAMP () vergangen sind, indem ich
UNIX_TIMESTAMP(discharged)
FROM subtrahiereUNIX_TIMESTAMP(admitted)
. Befindet sich der Patient noch im Bett (wie durch entlassenes Wesen angezeigtNULL
), weise ich JETZT die aktuelle Zeit zu () . Dann subtrahiere ich. Auf diese Weise erhalten Sie für jeden Patienten, der sich noch auf der Station befindet, eine minutengenaue Dauer.Dann summiere ich die Summe der Sekunden nach
patient_id
. Schließlich nehme ich die Sekunden für jeden Patienten und verwende SEC_TO_TIME () , um Stunden, Minuten und Sekunden des Patientenaufenthalts anzuzeigen.VERSUCHE ES !!!
quelle
A
undAA
). Ich denke, dass einer von ihnen genug ist.