首先,我的回答是基于Patient 应该被吸收到Test 中的假设,正如我之前的评论。我可以更新我的答案以包含列出的表结构的代码,或者根据要求。
(以下答案版本已针对以下测试数据进行了测试)
回答查询(如果第三次测试可能发生在相隔至少 24 小时的两次测试之间)
我首先将Test 的两个副本内部连接到自己,然后将结果内部连接到Citizen,以便对于每个Citizen,返回它们之间至少有24 小时的所有记录,无论如果第三条记录出现在它们之间且距离它们不到 24 小时。
生成的每条记录都应包含该匹配的测试时间(和测试 ID)。我在这里选择了主题来演示如何使用它们来通知用户,并作为语句扩展可能性的建议(如果用户希望扩展它)。
不应有重复记录。
SELECT Citizen.ssn AS 'Social Security Number',
Citizen.phone_number AS 'Phone Number',
greater_than_first_table.test_id AS 'First Test ID',
greater_than_first_table.test_time AS 'First Test Time',
greater_than_second_table.test_id AS 'Second Test ID',
greater_than_second_table.test_time AS 'Second Test Time'
FROM Test AS greater_than_first_table
INNER JOIN Test AS greater_than_second_table ON greater_than_first_table.ssn = greater_than_second_table.ssn AND
TIMESTAMPDIFF( HOUR,
greater_than_first_table.test_time,
greater_than_second_table.test_time ) >= 24
INNER JOIN Citizen ON greater_than_first_table.ssn = Citizen.ssn
WHERE greater_than_first_table.test_time BETWEEN '2021-10-03 00:00:00' AND '2021-10-05 00:00:00' AND
greater_than_second_table.test_time BETWEEN '2021-10-03 00:00:00' AND '2021-10-05 00:00:00';
回答查询(如上,但只有电话号码)
如果用户只对上面的电话号码感兴趣,那么可以使用下面的。
GROUP BY 用于消除重复结果。
SELECT Citizen.phone_number AS 'Phone Number'
FROM Test AS greater_than_first_table
INNER JOIN Test AS greater_than_second_table ON greater_than_first_table.ssn = greater_than_second_table.ssn AND
TIMESTAMPDIFF( HOUR,
greater_than_first_table.test_time,
greater_than_second_table.test_time ) >= 24
INNER JOIN Citizen ON greater_than_first_table.ssn = Citizen.ssn
WHERE greater_than_first_table.test_time BETWEEN '2021-10-03 00:00:00' AND '2021-10-05 00:00:00' AND
greater_than_second_table.test_time BETWEEN '2021-10-03 00:00:00' AND '2021-10-05 00:00:00'
GROUP BY Citizen.ssn;
回答查询(如果在下次测试前至少 24 小时)
以下是上述第一个语句的修改版本,它消除了第三个值出现在第一个值之后不到 24 小时的结果,即它只列出在下一个按时间顺序出现之前有 24 小时或更长时间的记录测试。
子查询用于为Citizen 生成相隔不到 24 小时的两个测试的记录。然后在主查询的第一个 INNER JOIN(LEFT 表)和子查询(@ 987654333@表)。主查询中的最后一个 WHERE 子句从子查询标识的结果中删除了这些记录。
SELECT Citizen.ssn AS 'Social Security Number',
Citizen.phone_number AS 'Phone Number',
greater_than_first_table.test_id AS 'First Test ID',
greater_than_first_table.test_time AS 'First Test Time',
greater_than_second_table.test_id AS 'Second Test ID',
greater_than_second_table.test_time AS 'Second Test Time'
FROM Test AS greater_than_first_table
INNER JOIN Test AS greater_than_second_table ON greater_than_first_table.ssn = greater_than_second_table.ssn AND
TIMESTAMPDIFF( HOUR,
greater_than_first_table.test_time,
greater_than_second_table.test_time ) >= 24
INNER JOIN Citizen ON greater_than_first_table.ssn = Citizen.ssn
LEFT JOIN
(
SELECT less_than_first_table.ssn AS less_than_ssn,
less_than_first_table.test_time AS less_than_test_time
FROM Test AS less_than_first_table
INNER JOIN Test AS less_than_second_table ON less_than_first_table.ssn = less_than_second_table.ssn AND
TIMESTAMPDIFF( HOUR,
less_than_first_table.test_time,
less_than_second_table.test_time ) > 0 AND
TIMESTAMPDIFF( HOUR,
less_than_first_table.test_time,
less_than_second_table.test_time ) < 24
WHERE less_than_first_table.test_time BETWEEN '2021-10-03 00:00:00' AND '2021-10-05 00:00:00' AND
less_than_second_table.test_time BETWEEN '2021-10-03 00:00:00' AND '2021-10-05 00:00:00'
) AS less_than_table ON greater_than_first_table.ssn = less_than_table.less_than_ssn AND
greater_than_first_table.test_time = less_than_table.less_than_test_time
WHERE greater_than_first_table.test_time BETWEEN '2021-10-03 00:00:00' AND '2021-10-05 00:00:00' AND
greater_than_second_table.test_time BETWEEN '2021-10-03 00:00:00' AND '2021-10-05 00:00:00' AND
less_than_table.less_than_ssn IS NULL;
测试数据语句
DROP TABLE IF EXISTS Citizen;
DROP TABLE IF EXISTS Test;
CREATE TABLE Citizen
(
ssn VARCHAR( 50 ) NOT NULL,
phone_number VARCHAR( 50 ) NOT NULL,
CONSTRAINT pkc_citizen PRIMARY KEY ( ssn ),
CONSTRAINT unc_citizen_phone_number UNIQUE ( phone_number )
);
CREATE TABLE Test
(
test_id INT NOT NULL AUTO_INCREMENT,
ssn VARCHAR( 50 ) NOT NULL,
test_time DATETIME,
CONSTRAINT pkc_test PRIMARY KEY( test_id ),
CONSTRAINT fkc_test_citizen FOREIGN KEY ( ssn ) REFERENCES Citizen( ssn )
);
INSERT INTO Citizen VALUES ( 'THX-1138', '555-555-555' );
INSERT INTO Citizen VALUES ( 'TK4218', '555-111-111' );
INSERT INTO Citizen VALUES ( 'R2-D2', '555-222-222' );
INSERT INTO Test ( ssn, test_time ) VALUES ( 'THX-1138', '2021-10-02 22:34:51' );
INSERT INTO Test ( ssn, test_time ) VALUES ( 'THX-1138', '2021-10-03 09:00:00' );
INSERT INTO Test ( ssn, test_time ) VALUES ( 'THX-1138', '2021-10-03 10:00:00' );
INSERT INTO Test ( ssn, test_time ) VALUES ( 'THX-1138', '2021-10-04 11:34:51' );
INSERT INTO Test ( ssn, test_time ) VALUES ( 'TK4218', '2021-10-03 10:34:51' );
INSERT INTO Test ( ssn, test_time ) VALUES ( 'TK4218', '2021-10-04 11:34:51' );