有没有办法在同一列上进行 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 个交易。我想找到历史记录中的所有行:
- A 的字段名称和 B 的旧值
- C 的字段名和 D 的旧值
- 相同的 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'
我目前有一个不优雅的解决方案,需要一次遍历数千行,我想知道是否可以使用单个 SQL 语句来完成此操作。
我有一个名为 history
的数据库 table,它在另一个名为 inventory
的数据库中保存了所有事务的记录。两个数据库共享一个名为 pKey
的列(外键)。
我的库存数据库:
| ID | pKey | model | room | ip | active | ... |
我的历史数据库:pKey是外键
| ID | pKey | fieldName | oldValue | newValue |
在历史数据库中,一个 pKey 可以有超过 20 个交易。我想找到历史记录中的所有行:
- A 的字段名称和 B 的旧值
- C 的字段名和 D 的旧值
- 相同的 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'