我目前有一个不优雅的解决方案,需要一次迭代数千行,我想知道是否可以使用单个SQL语句执行此操作。
我有一个名为history
的数据库表,其中包含另一个名为inventory
的数据库上的所有事务的记录。两个数据库共享一个名为pKey
的列(外键)。
我的库存数据库:
| ID | pKey | model | room | ip | active | ... |
我的历史数据库: pKey是外键
| ID | pKey | fieldName | oldValue | newValue |
在历史数据库中,单个pKey可以有超过20个事务。我想找到历史中包含的所有行:
即。假设我们发现历史表中有一行,其fieldName为A,旧值为B,只有在搜索fieldName为C和oldValue的行时,与该行关联的pKey才会生效。 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%'
编辑:我在这里写下自己的陈述是错误的;我只想选择pKey结果。
答案 0 :(得分:2)
当您需要执行SELF-JOIN时,您必须为要加入的表的副本提供别名。
请查看下面的查询 - 这里双方都有别名:
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
条款中,您在问题中提到了条件:
(...)说我们发现历史表中有一行 fieldName of A和old Value of B,结果只有在有效时才有效 与该行关联的pKey也会在搜索行时出现 fieldName为C,oldValue为D
我希望我能很好地理解这个问题,它可能对你有所帮助。
答案 1 :(得分:2)
您必须将历史的两个实例标识为单独的元素。使用你的" 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'
答案 2 :(得分:1)
如果进行自联接,则通常需要分配表别名,以便能够明确地引用任一表的任何列。因此,你可能想要这样的东西:
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'
当然,您可以根据需要编写选择列表,包括只选择*
,但我建议至少指定列别名以帮助您理清哪些数据来自哪个表。