How to extract desired results from different columns
-
21-02-2021 - |
سؤال
In order to conserve space and eliminate duplicates, I have the following table of distances between locations:
patientIDa | patientIDb | distance |
1 | 2 | 4.5 |
1 | 3 | 2.8 |
1 | 4 | 1.3 |
1 | 5 | 0.9 |
2 | 3 | 2.0 |
2 | 4 | 5.3 |
2 | 5 | 4.4 |
3 | 4 | 4.4 |
3 | 5 | 3.7 |
4 | 5 | 4.5 |
I run the following query to get the three closest distances to patient #3:
Select * From Distances Where (patientIDa=3 OR patientIDb=3)
Order By distance
Limit 3;
Result set:
patientIDa patientIDb distance
2 | 3 | 2.0
1 | 3 | 2.8
3 | 5 | 3.7
How would I go about extracting the corresponding patientIDx's (2, 1, 5), as they are in different columns? Running MySQL 5.6 on aws. Apologies on the formatting.
As an aside, is this bad design to begin with? I'm fairly new at DB tech.
المحلول
SELECT patientIDa, patientIDb, distance
FROM Distances
WHERE patientIDa=3
UNION ALL
SELECT patientIDb, patientIDa, distance
FROM Distances
WHERE patientIDb=3
ORDER BY distance
LIMIT 3;
نصائح أخرى
And if you want to avoid a UNION
- not certain of performance here, but this might be better (see fiddle here) - you don't have to query the table twice as for @Akina's query! You might want to check with a large dataset.
Create and populate table:
CREATE table pat_dis
(
p1 INT,
p2 INT,
dis FLOAT
);
INSERT INTO pat_dis VALUES
( 1, 2, 1.1),
( 1, 5, 1.5),
( 2, 3, 2.0),
( 1, 3, 2.8),
( 3, 5, 3.7),
( 8, 3, 9.9),
( 4, 7, 0.1); -- << extra record no paitent 3 and small distance
And then run this query:
SELECT
CASE
WHEN LEAST(p1, p2) < 3 THEN p1
WHEN GREATEST (p1, p2 > 3) THEN p2
END AS patient,
dis AS distance
FROM pat_dis
WHERE (p1 = 3 OR p2 = 3)
ORDER BY distance
LIMIT 3;
Result:
patient distance
2 2
1 2.8
5 3.7
Et voilà! Following the OP's comment on my elementary error, with the new WHERE
clause, this is now the correct answer even if there are patients with a shorter distance between them but neither of whom is patient 3. Both fiddles have been amended.
As an aside, I would recommend that you upgrade to version 8 of MySQL. Apart from all sorts of goodies like Common Table Expressions
and Window functions
, you get CHECK
constraints which allow you to write this (see fiddle here):
CREATE table pat_dis
(
p1 INT,
p2 INT,
CONSTRAINT patient_not_same CHECK (p1 != p2), -- version 8 - new line!
dis FLOAT
);
Now try:
INSERT INTO pat_dis VALUES (3, 3, 3.6); -- cannot insert identical patients!
-- see same line in 1st fiddle.
Result:
Check constraint 'patient_not_same' is violated.