Groupwise 最大记录查找合同和最新状态
Groupwise maximum record lookup for contracts and latest status
我正在寻求帮助,因为我似乎无法处理 SQL 查询。
我有两个table:
- 合同 - 合同列表与相关合作伙伴一起保存
CREATE TABLE `contracts` (
`id` varchar(5) NOT NULL,
`partner` varchar(12) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
)
- locks - 合约状态列表
CREATE TABLE `locks` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` enum('unlock','templock','lock','permalock') DEFAULT NULL,
`contractID` varchar(5) NOT NULL,
`partnerID` varchar(12) NOT NULL,
`stamp` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`user` varchar(32) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
)
我正在尝试获取给定合作伙伴的最新合同状态列表:
SELECT c.id, c.partner ,l.`type`, l.stamp, l.id
FROM contracts c
LEFT JOIN locks l
ON c.id = l.contractID
WHERE partner="2000000301"
GROUP BY c.id ASC
我能够得到结果,但它没有正确指示最后一个状态 - 它“需要”第一个出现:(,而我需要最后一个。
我尝试了顺序方法,即我首先进行查询以检索合约的最后状态:
SELECT max(l.id), l.partnerID ,l.contractID ,l.stamp ,l.`type`
FROM locks l
WHERE l.partnerID = "2000000301" and l.contractID ="35274";
它工作正常,但如果我尝试将其实现到主查询,使用 'LEFT JOIN(...)'
SELECT *
FROM contracts
LEFT JOIN (
SELECT max(ll.id), ll.contractID, ll.partnerID, ll.stamp, ll.`type`
FROM locks ll
WHERE ll.partnerID = contracts.partner <-- error :(
) l
ON contracts.id = l.contractID
WHERE partner="2000000301"
ORDER BY contracts.id ASC
'contracts' table 中 'contractID' 字段的可用性存在问题,我得到一个错误 :(
SQL Error [1054] [42S22]: (conn=180) Unknown column 'contracts.partner' in 'where clause'
我已经失去了方法的概念。
我认为它有效:)
SELECT c.id ,c.partner ,l.stamp ,l.`type`
FROM contracts c
LEFT JOIN (
SELECT l.contractID, l.partnerID, l.stamp, l.`type`
FROM locks l INNER JOIN (
SELECT contractID, max(id) as max_id
FROM locks
group by contractID
) m
ON l.contractID=m.contractID and l.id=m.max_id
) l
ON c.id = l.contractID
WHERE c.partner="2000000301"
ORDER BY c.id ASC
这称为 groupwise-maximum 问题。
您的 locks
table 似乎有时会更新,这些更新会更改 stamp
时间戳列。因此,您的问题是为每个 contractID
报告最新的——最近的——locks
记录。从子查询开始以确定每个合约的最新 stamp
。
SELECT MAX(stamp) stamp, contractID
FROM locks
GROUP BY contractID
然后在您的主查询中使用该子查询来选择 locks
的适当行。
SELECT c.id ,c.partner ,l.stamp ,l.`type`
FROM contracts c
LEFT JOIN (
SELECT MAX(stamp) stamp, contractID
FROM locks
GROUP BY contractID
) latest ON c.contractID=latest.contractID
LEFT JOIN locks l ON c.contractID = l.contractID
AND latest.stamp = l.stamp
WHERE c.partner="2000000301"
ORDER BY c.id ASC
请注意,最新的 locks
记录不一定是具有最大 id
值的记录。
当您的锁 table 很大时,该索引将通过启用子查询执行 loose index scan.
来帮助提高查询性能
ALTER TABLE locks ADD INDEX contractid_stamp (contractID, stamp);
而且,您不需要在同一列上同时使用 PRIMARY KEY 和 UNIQUE KEY。 PRIMARY KEY 的作用是保证唯一性。将两个键都放在 table 上会无缘无故地减慢 INSERT。
我正在寻求帮助,因为我似乎无法处理 SQL 查询。
我有两个table:
- 合同 - 合同列表与相关合作伙伴一起保存
CREATE TABLE `contracts` (
`id` varchar(5) NOT NULL,
`partner` varchar(12) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
)
- locks - 合约状态列表
CREATE TABLE `locks` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` enum('unlock','templock','lock','permalock') DEFAULT NULL,
`contractID` varchar(5) NOT NULL,
`partnerID` varchar(12) NOT NULL,
`stamp` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`user` varchar(32) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
)
我正在尝试获取给定合作伙伴的最新合同状态列表:
SELECT c.id, c.partner ,l.`type`, l.stamp, l.id
FROM contracts c
LEFT JOIN locks l
ON c.id = l.contractID
WHERE partner="2000000301"
GROUP BY c.id ASC
我能够得到结果,但它没有正确指示最后一个状态 - 它“需要”第一个出现:(,而我需要最后一个。
我尝试了顺序方法,即我首先进行查询以检索合约的最后状态:
SELECT max(l.id), l.partnerID ,l.contractID ,l.stamp ,l.`type`
FROM locks l
WHERE l.partnerID = "2000000301" and l.contractID ="35274";
它工作正常,但如果我尝试将其实现到主查询,使用 'LEFT JOIN(...)'
SELECT *
FROM contracts
LEFT JOIN (
SELECT max(ll.id), ll.contractID, ll.partnerID, ll.stamp, ll.`type`
FROM locks ll
WHERE ll.partnerID = contracts.partner <-- error :(
) l
ON contracts.id = l.contractID
WHERE partner="2000000301"
ORDER BY contracts.id ASC
'contracts' table 中 'contractID' 字段的可用性存在问题,我得到一个错误 :(
SQL Error [1054] [42S22]: (conn=180) Unknown column 'contracts.partner' in 'where clause'
我已经失去了方法的概念。
我认为它有效:)
SELECT c.id ,c.partner ,l.stamp ,l.`type`
FROM contracts c
LEFT JOIN (
SELECT l.contractID, l.partnerID, l.stamp, l.`type`
FROM locks l INNER JOIN (
SELECT contractID, max(id) as max_id
FROM locks
group by contractID
) m
ON l.contractID=m.contractID and l.id=m.max_id
) l
ON c.id = l.contractID
WHERE c.partner="2000000301"
ORDER BY c.id ASC
这称为 groupwise-maximum 问题。
您的 locks
table 似乎有时会更新,这些更新会更改 stamp
时间戳列。因此,您的问题是为每个 contractID
报告最新的——最近的——locks
记录。从子查询开始以确定每个合约的最新 stamp
。
SELECT MAX(stamp) stamp, contractID
FROM locks
GROUP BY contractID
然后在您的主查询中使用该子查询来选择 locks
的适当行。
SELECT c.id ,c.partner ,l.stamp ,l.`type`
FROM contracts c
LEFT JOIN (
SELECT MAX(stamp) stamp, contractID
FROM locks
GROUP BY contractID
) latest ON c.contractID=latest.contractID
LEFT JOIN locks l ON c.contractID = l.contractID
AND latest.stamp = l.stamp
WHERE c.partner="2000000301"
ORDER BY c.id ASC
请注意,最新的 locks
记录不一定是具有最大 id
值的记录。
当您的锁 table 很大时,该索引将通过启用子查询执行 loose index scan.
来帮助提高查询性能ALTER TABLE locks ADD INDEX contractid_stamp (contractID, stamp);
而且,您不需要在同一列上同时使用 PRIMARY KEY 和 UNIQUE KEY。 PRIMARY KEY 的作用是保证唯一性。将两个键都放在 table 上会无缘无故地减慢 INSERT。