有没有办法在同一列上进行 SELF JOIN?

Is there a way to do a SELF JOIN on on the same column?

我目前有一个不优雅的解决方案,需要一次遍历数千行,我想知道是否可以使用单个 SQL 语句来完成此操作。

我有一个名为 history 的数据库 table,它在另一个名为 inventory 的数据库中保存了所有事务的记录。两个数据库共享一个名为 pKey 的列(外键)。

我的库存数据库:

| ID | pKey | model | room | ip | active | ... |

我的历史数据库:pKey是外键

| ID | pKey | fieldName | oldValue | newValue |

在历史数据库中,一个 pKey 可以有超过 20 个交易。我想找到历史记录中的所有行:

  1. A 的字段名称和 B 的旧值
  2. C 的字段名和 D 的旧值
  3. 相同的 pKey。

即假设我们发现在历史记录 table 中有一行字段名称为 A,旧值为 B,只有当与该行关联的 pKey 也出现在具有字段名称的行的搜索中时,结果才有效C 的旧值和 D 的旧值

经过一些研究后,SELF JOIN 似乎是一个不错的选择,但我遇到了错误,因为我试图在同一列上进行 SELF JOIN。这是我的声明:

SELECT pKey FROM `history` INNER JOIN history ON history.pKey=history.pKey WHERE `fieldName` = 'ipAddress' AND `oldValue` LIKE '129.97%'

编辑: 我在这里写的声明有误;我只是想 select pKey 结果。

当您需要执行 SELF-JOIN 时,您必须为要加入的 table 副本指定一个别名。

请在下面查找查询 - 此处双方都使用了别名:

SELECT 
    history_AB.pKey
FROM 
    history  AS  history_AB
    INNER JOIN history  AS  history_CD 
        ON history_AB.pKey = history_CD.pKey 
WHERE 
    (history_AB.fieldName = 'A' AND history_AB.oldValue LIKE 'B%')
    AND (history_CD.fieldName = 'C' AND history_CD.oldValue LIKE 'D%')

WHERE 子句中有您在问题中提到的条件:

(...) say we find that we have a row in the history table with fieldName of A and old Value of B, the result will only be valid if the pKey associated with that row also turns up in the search for rows with a fieldName of C and oldValue of D

我希望我已经很好地理解了这个问题,它可能会对你有所帮助。

如果您进行自连接,那么您通常需要分配 table 别名,以便能够明确地引用 table 任何 列=].因此,您可能想要这样的东西:

SELECT
  histA.pKey AS pKey,
  histA.newValue AS newA,
  histC.newValue AS newC,
FROM
  history histA
  INNER JOIN history histC
    ON histA.pKey = histC.pKey
WHERE
  histA.fieldName = 'A'
  AND histA.oldValue = 'B'
  AND histC.fieldName = 'C'
  AND histC.oldValue = 'D'

当然,你可以随意编写选择列表,包括只选择*,但我建议至少分配列别名以帮助你理清哪些数据来自哪些table .

您必须将历史的两个实例识别为不同的元素。使用您的 "ABCD" 示例而不是您的语句:

SELECT * FROM history h1 
INNER JOIN history h2
ON h1.pKey=h2.pKey 
WHERE h1.fieldName = 'A' AND h1.oldValue = 'B' 
AND h2.fieldName = 'C' AND h2.oldValue = 'D'