【问题标题】:Self Join With Multiple Conditions多条件自加入
【发布时间】:2016-06-13 22:26:07
【问题描述】:

我正在使用 mysql 来存储我的化学分析。并使用 html/php 过滤结果并生成查询以获取我想要的结果。现在事情对我来说变得复杂了,我正在尝试自行加入表格以应用所有过滤器。

我的表格设计是这样的,有超过 50k 行。

+--------+---------+-------------+----------------+
| Column |  Type   |    Index    |                |
+--------+---------+-------------+----------------+
| RID    | int     | primary_key | auto increment |
| ID     | int     | index       |                |
| Type   | int     |             |                |
| Order  | int     |             |                |
| Num    | int     |             |                |
| Val1   | decimal |             |                |
| Val2   | decimal |             |                |
+--------+---------+-------------+----------------+

每个样本都有一个ID、不同的类型顺序Val1Val2Num类型分析的结果。现在有 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 的原因。

【问题讨论】:

  • 你能列出结构还是它的数据......你在 where 子句中引用了“SType”。此外,您正在寻找基于每个“ID”的结果?并且每个化学分析都需要在特定的订单中?例如条件1必须在条件2之前找到,等等条件3?从满足所有 3 个条件的那些中......这些是您想要的最终记录?
  • @DRapp 我在这里写了查询,所以 SType 写错了。是“类型”。正如我所说,需要通过过滤器的 ID 的所有数据。例如,如果我的条件为“类型 1,num 5 小于 20 val2”,则 Val2 仍将显示 29.62、22,96。因为有参数通过了 ID 118 的过滤器。

标签: mysql join inner-join self-join


【解决方案1】:

所以,你对桌子的要求是

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 个不同的标准(Type、num、Val1、Val2)

虽然可能有“更好”的解决方案(在性能方面或更易于阅读的代码方面),但最简单的方法是创建不同的条件对,除非您处理数百万条记录,否则这应该没问题。

根据您的要求,我认为您需要获取以下行集:

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 附加到每个独立的查询中。

【讨论】:

  • 感谢您的回复。我想我忘了提。所有其他数据必须使用过滤后的 ID 显示。
  • 谢谢,我会试试的。
  • 我认为 UNION 会造成严重的性能问题。我的表已经有 50k 行,我不想每次都过滤一个 id。
【解决方案2】:

我已经解决了我的问题,即同时查询相同的数字和类型,而不是通过单独的连接来获取它们。这样,相同 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

【讨论】:

    猜你喜欢
    • 2013-07-22
    • 1970-01-01
    • 1970-01-01
    • 2016-03-06
    • 2013-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多