具有多个条件的自连接
Self Join With Multiple Conditions
我正在使用 mysql 来存储我的化学分析。并使用 html/php 过滤结果并生成查询以获取我想要的结果。现在事情对我来说变得复杂了,我正在尝试自己加入 table 以应用所有过滤器。
我的 table 设计是这样的,有超过 50k 行。
+--------+---------+-------------+----------------+
| Column | Type | Index | |
+--------+---------+-------------+----------------+
| RID | int | primary_key | auto increment |
| ID | int | index | |
| Type | int | | |
| Order | int | | |
| Num | int | | |
| Val1 | decimal | | |
| Val2 | decimal | | |
+--------+---------+-------------+----------------+
每个样本都有一个 ID,不同的 types 和 order。 Val1 和 Val2 是 Num 类型分析的结果。现在有42个不同的Num。
例如,如果我的过滤器是这样的,
Select Types (1,3,9)
Select ANum (0,5)
Type 1, Num 5 should be bigger than 10 In Val2
Type 1, Num 5, should be smaller than 30 In Val2
Type 3, Num 0, should be smaller than 8 In Val1
我正在使用该查询生成结果。
SELECT analyse.* FROM analyse
INNER JOIN
(SELECT ID FROM analyse WHERE Type = 1 AND Num = 5 AND Val2 < 30) AS a1 ON a1.SID = analyse.SID
INNER JOIN
(SELECT SID FROM WHERE Type = 1 AND Num = 5 AND Val2 > 10) AS a2 ON a2.SID = analyse.SID
INNER JOIN
(SELECT SID FROM analyse WHERE Type = 3 AND Num = 0 AND Val1 > 8) AS a3 ON a2.SID = analyse.SID
WHERE Type IN (1,3,9) AND Num IN (0,5) ORDER BY ID, Type, Order, Num ASC
+-----+------+-------+---------------+--------------+--------------+--------------+
| ID | Type | Order | Val1[Num[0]] | Val2[Num[0]] | Val1[Num[5]] | Val2[Num[5]] |
+-----+------+-------+---------------+--------------+--------------+--------------+
| ... | ... | ... | ... | ... | ... | ... |
| 118 | 1 | 1 | 10.9000 | 2.2083 | 3.5056 | 15.2627 |
| 118 | 1 | 2 | 9.5000 | 1.9246 | 2.0305 | 11.7049 |
| 118 | 1 | 3 | 7.9000 | 1.6005 | 2.4274 | 16.6597 |
| 118 | 2 | 1 | 10.9000 | 2.2083 | 3.5056 | 15.2627 |
| 118 | 3 | 2 | 20.4000 | 4.1329 | 2.8187 | 22.9676 |
| 118 | 4 | 3 | 28.3000 | 5.7334 | 2.7094 | 29.6273 |
| 119 | 1 | 1 | 27.2000 | 6.8635 | 0.5506 | 14.9084 |
| 119 | 1 | 2 | 25.9000 | 6.5355 | 0.4249 | 10.9550 |
| 119 | 3 | 1 | 27.2000 | 6.8635 | 0.5506 | 14.9084 |
| 119 | 3 | 2 | 53.1000 | 13.3989 | 0.4893 | 25.8634 |
| ... | ... | ... | ... | ... | ... | ... |
+-----+------+-------+---------------+--------------+--------------+--------------+
期望的输出应该是这样的。但是,由于还有其他 Val1 和 Val2 值具有相同的 ID、相同的类型但顺序不同,我猜 INNER JOIN 无法按预期工作。总是有比我的过滤器更大和更小的值出现。其中一些从未显示过。
抱歉,如果它太长了。我找不到正确的语句或结构。有什么建议吗?
编辑:抱歉。我忘了提及所有其他必须显示 ID 的数据。这就是我尝试使用 join 的原因。
因此,您对 table 的要求是
Select Types (1,3,9)
Select Num (0,5)
Type 1, Num 5 should be bigger than 10 In Val2
Type 1, Num 5, should be smaller than 30 In Val2
Type 3, Num 0, should be smaller than 8 In Val1
基本上有 4 个不同的标准需要评估(类型、数量、Val1、Val2)
虽然可能有 "better" 解决方案(在性能或更易于阅读的代码方面),但最简单的方法是创建不同的条件对,除非您处理数百万条记录,否则应该没问题。
根据您的要求,我认为您需要获取以下行集:
1.) Type = 1, Num = 5, Val2 > 10
2.) Type = 1, Num = 5, Val2 < 30
3.) Type = 3, Num = 0, Val1 < 8
4.) Type = 9
因此,这将是“4 个显式”查询的联合:
SELECT * FROM analyse WHERE Type = 1 AND Num = 5 AND Val2 > 10
UNION
SELECT * FROM analyse WHERE Type = 1 AND Num = 5 AND Val2 < 10
UNION
SELECT * FROM analyse WHERE Type = 3 AND Num = 0 AND Val1 < 8
UNION
SELECT * FROM analyse WHERE Type = 9
要通过 id 过滤最终结果,您可以简单地使用:
SELECT * FROM (
SELECT * FROM analyse WHERE Type = 1 AND Num = 5 AND Val2 > 10
UNION
SELECT * FROM analyse WHERE Type = 1 AND Num = 5 AND Val2 < 10
UNION
SELECT * FROM analyse WHERE Type = 3 AND Num = 0 AND Val1 < 8
UNION
SELECT * FROM analyse WHERE Type = 9
) as tempTable WHERE id = 118
- 或者只是将 id 附加到每个独立的查询。
我已经通过同时查询相同的 Nums 和 Types 而不是使用单独的连接获取它们来解决了我的问题。这样,其他相同 Num 和 Type 的数据将无法通过过滤器。
对于那个条件
Select Types (1,3,9)
Select ANum (0,5)
Type 1, Num 5 should be bigger than 10 In Val2
Type 1, Num 5, should be smaller than 30 In Val2
Type 3, Num 0, should be smaller than 8 In Val1
查询应该是这样的,
SELECT analyse.* FROM analyse
INNER JOIN
(SELECT ID FROM analyse WHERE Type = 1 AND Num = 5 AND Val2 < 30 AND Val2 > 10) AS a1 ON a1.SID = analyse.SID
(SELECT SID FROM analyse WHERE Type = 3 AND Num = 0 AND Val1 > 8) AS a3 ON a2.SID = analyse.SID
WHERE Type IN (1,3,9) AND Num IN (0,5) ORDER BY ID, Type, Order, Num ASC
我正在使用 mysql 来存储我的化学分析。并使用 html/php 过滤结果并生成查询以获取我想要的结果。现在事情对我来说变得复杂了,我正在尝试自己加入 table 以应用所有过滤器。
我的 table 设计是这样的,有超过 50k 行。
+--------+---------+-------------+----------------+
| Column | Type | Index | |
+--------+---------+-------------+----------------+
| RID | int | primary_key | auto increment |
| ID | int | index | |
| Type | int | | |
| Order | int | | |
| Num | int | | |
| Val1 | decimal | | |
| Val2 | decimal | | |
+--------+---------+-------------+----------------+
每个样本都有一个 ID,不同的 types 和 order。 Val1 和 Val2 是 Num 类型分析的结果。现在有42个不同的Num。
例如,如果我的过滤器是这样的,
Select Types (1,3,9)
Select ANum (0,5)
Type 1, Num 5 should be bigger than 10 In Val2
Type 1, Num 5, should be smaller than 30 In Val2
Type 3, Num 0, should be smaller than 8 In Val1
我正在使用该查询生成结果。
SELECT analyse.* FROM analyse
INNER JOIN
(SELECT ID FROM analyse WHERE Type = 1 AND Num = 5 AND Val2 < 30) AS a1 ON a1.SID = analyse.SID
INNER JOIN
(SELECT SID FROM WHERE Type = 1 AND Num = 5 AND Val2 > 10) AS a2 ON a2.SID = analyse.SID
INNER JOIN
(SELECT SID FROM analyse WHERE Type = 3 AND Num = 0 AND Val1 > 8) AS a3 ON a2.SID = analyse.SID
WHERE Type IN (1,3,9) AND Num IN (0,5) ORDER BY ID, Type, Order, Num ASC
+-----+------+-------+---------------+--------------+--------------+--------------+
| ID | Type | Order | Val1[Num[0]] | Val2[Num[0]] | Val1[Num[5]] | Val2[Num[5]] |
+-----+------+-------+---------------+--------------+--------------+--------------+
| ... | ... | ... | ... | ... | ... | ... |
| 118 | 1 | 1 | 10.9000 | 2.2083 | 3.5056 | 15.2627 |
| 118 | 1 | 2 | 9.5000 | 1.9246 | 2.0305 | 11.7049 |
| 118 | 1 | 3 | 7.9000 | 1.6005 | 2.4274 | 16.6597 |
| 118 | 2 | 1 | 10.9000 | 2.2083 | 3.5056 | 15.2627 |
| 118 | 3 | 2 | 20.4000 | 4.1329 | 2.8187 | 22.9676 |
| 118 | 4 | 3 | 28.3000 | 5.7334 | 2.7094 | 29.6273 |
| 119 | 1 | 1 | 27.2000 | 6.8635 | 0.5506 | 14.9084 |
| 119 | 1 | 2 | 25.9000 | 6.5355 | 0.4249 | 10.9550 |
| 119 | 3 | 1 | 27.2000 | 6.8635 | 0.5506 | 14.9084 |
| 119 | 3 | 2 | 53.1000 | 13.3989 | 0.4893 | 25.8634 |
| ... | ... | ... | ... | ... | ... | ... |
+-----+------+-------+---------------+--------------+--------------+--------------+
期望的输出应该是这样的。但是,由于还有其他 Val1 和 Val2 值具有相同的 ID、相同的类型但顺序不同,我猜 INNER JOIN 无法按预期工作。总是有比我的过滤器更大和更小的值出现。其中一些从未显示过。
抱歉,如果它太长了。我找不到正确的语句或结构。有什么建议吗?
编辑:抱歉。我忘了提及所有其他必须显示 ID 的数据。这就是我尝试使用 join 的原因。
因此,您对 table 的要求是
Select Types (1,3,9)
Select Num (0,5)
Type 1, Num 5 should be bigger than 10 In Val2
Type 1, Num 5, should be smaller than 30 In Val2
Type 3, Num 0, should be smaller than 8 In Val1
基本上有 4 个不同的标准需要评估(类型、数量、Val1、Val2)
虽然可能有 "better" 解决方案(在性能或更易于阅读的代码方面),但最简单的方法是创建不同的条件对,除非您处理数百万条记录,否则应该没问题。
根据您的要求,我认为您需要获取以下行集:
1.) Type = 1, Num = 5, Val2 > 10
2.) Type = 1, Num = 5, Val2 < 30
3.) Type = 3, Num = 0, Val1 < 8
4.) Type = 9
因此,这将是“4 个显式”查询的联合:
SELECT * FROM analyse WHERE Type = 1 AND Num = 5 AND Val2 > 10
UNION
SELECT * FROM analyse WHERE Type = 1 AND Num = 5 AND Val2 < 10
UNION
SELECT * FROM analyse WHERE Type = 3 AND Num = 0 AND Val1 < 8
UNION
SELECT * FROM analyse WHERE Type = 9
要通过 id 过滤最终结果,您可以简单地使用:
SELECT * FROM (
SELECT * FROM analyse WHERE Type = 1 AND Num = 5 AND Val2 > 10
UNION
SELECT * FROM analyse WHERE Type = 1 AND Num = 5 AND Val2 < 10
UNION
SELECT * FROM analyse WHERE Type = 3 AND Num = 0 AND Val1 < 8
UNION
SELECT * FROM analyse WHERE Type = 9
) as tempTable WHERE id = 118
- 或者只是将 id 附加到每个独立的查询。
我已经通过同时查询相同的 Nums 和 Types 而不是使用单独的连接获取它们来解决了我的问题。这样,其他相同 Num 和 Type 的数据将无法通过过滤器。
对于那个条件
Select Types (1,3,9)
Select ANum (0,5)
Type 1, Num 5 should be bigger than 10 In Val2
Type 1, Num 5, should be smaller than 30 In Val2
Type 3, Num 0, should be smaller than 8 In Val1
查询应该是这样的,
SELECT analyse.* FROM analyse
INNER JOIN
(SELECT ID FROM analyse WHERE Type = 1 AND Num = 5 AND Val2 < 30 AND Val2 > 10) AS a1 ON a1.SID = analyse.SID
(SELECT SID FROM analyse WHERE Type = 3 AND Num = 0 AND Val1 > 8) AS a3 ON a2.SID = analyse.SID
WHERE Type IN (1,3,9) AND Num IN (0,5) ORDER BY ID, Type, Order, Num ASC