Select 个来自 2 MySQL 个表的非重复记录
Select non-duplicated records from 2 MySQL tables
我有 2 个 table,即:
1.下载门票
2. 兑换门票
每个 table 都有属性 "ticketid"。
我想找到下载票但没有兑换票的人 - 本质上,找到非重复(唯一)的票证。
我的查询(PHP)如下:
$sql = "
SELECT ticketid
FROM (
SELECT ticketid
FROM downloadedtickets
UNION ALL
SELECT ticketid
FROM redeemedtickets
)
GROUP BY ticketid
HAVING COUNT(*) = 1";
我没有从中得到任何输出。
执行此操作的一个好方法是左连接,并测试 NULL。
SELECT d.ticketid
FROM downloadedtickets d
LEFT JOIN redeemedtickets r USING(ticketid)
WHERE r.ticketid IS NULL
LEFT JOIN 操作为每张下载的门票及其兑换创建一个结果行。在没有兑换的地方,redeemed.ticketid 为 NULL,因此此查询仅使用 WHERE 来 select 那些项目。
您应该指定并汇总您正在统计的字段。见下文:
$sql = "SELECT COUNT(ticketid)ticketid FROM downloadedtickets UNION ALL SELECT ticketid FROM redeemedtickets GROUP BY ticketid HAVING COUNT(ticketid) = 1";
我会使用 NOT EXISTS
、NOT IN
或 LEFT JOIN
来解决这个问题。这是后一个版本:
select d.*
from downloadedtickets d left outer join
redeemedtickets r
on d.ticketid = r.ticketid
where r.ticketid is null;
您的查询似乎应该 return 指定的结果。对于您得到的结果(无行)的一种可能解释是没有任何未兑换的已下载门票。
此查询似乎假定 ticketid
在 downloadedtickets
table 中是唯一的,并且在 redeemedtickets
table 中是唯一的...是这样,但我们没有从我们提供的规范中获得该信息。 (如果不是这种情况,那么仅来自 downloadedtickets
table 的 ticketid
的 COUNT(*) 可能大于一个。
ticketid
是用于 "match" 来自两个 table 的行的正确列吗?我们假设它是,因为这就是您的查询所使用的。 (如果不是,那也可以解释您得到的结果。)
您的查询采用以下形式(更容易阅读):
SELECT t.ticketid
FROM ( SELECT d.ticketid
FROM downloadedtickets d
UNION ALL
SELECT r.ticketid
FROM redeemedtickets r
) t
GROUP BY t.ticketid
HAVING COUNT(*) = 1
我们注意到,对于 redeemedtickets
中不在 downloadedtickets
中的行,此查询有可能 return ticketid
。可能有某种保证不会发生这种情况,但同样,规范中没有该信息。
对于大型集合,实现内联视图的成本可能很高。
就个人而言,我更喜欢使用具有更高效 "anti-join" 模式的查询:
SELECT d.ticketid
FROM downloadedtickets d
LEFT
JOIN redeemedtickets r
ON r.ticketid = d.ticketid
WHERE r.ticketid IS NULL
ORDER BY d.ticketid
这实际上是说,return 来自 downloadedtickets
的所有行,以及来自 redeemed
票的任何 "matching" 行。 LEFT
关键字使它成为一个 "outer" 连接,因此我们从左侧的 table 中获取所有行,无论左侧的 table 中是否存在匹配的行右边。诀窍是 WHERE
子句中的谓词,它过滤掉所有匹配的行。 (如果匹配,我们保证 redeemedtickets
中的 ticketid
将是非 NULL。因此,table 中唯一具有 NULL 值的行将是来自downloadedtickets
没有匹配项。
此查询可以有效利用 redeemedtickets
上的索引,其前导列为 ticketid
。
这不是唯一会 return 指定结果的查询,还有其他查询模式可以 return 等效结果。
我有 2 个 table,即: 1.下载门票 2. 兑换门票
每个 table 都有属性 "ticketid"。
我想找到下载票但没有兑换票的人 - 本质上,找到非重复(唯一)的票证。
我的查询(PHP)如下:
$sql = "
SELECT ticketid
FROM (
SELECT ticketid
FROM downloadedtickets
UNION ALL
SELECT ticketid
FROM redeemedtickets
)
GROUP BY ticketid
HAVING COUNT(*) = 1";
我没有从中得到任何输出。
执行此操作的一个好方法是左连接,并测试 NULL。
SELECT d.ticketid
FROM downloadedtickets d
LEFT JOIN redeemedtickets r USING(ticketid)
WHERE r.ticketid IS NULL
LEFT JOIN 操作为每张下载的门票及其兑换创建一个结果行。在没有兑换的地方,redeemed.ticketid 为 NULL,因此此查询仅使用 WHERE 来 select 那些项目。
您应该指定并汇总您正在统计的字段。见下文:
$sql = "SELECT COUNT(ticketid)ticketid FROM downloadedtickets UNION ALL SELECT ticketid FROM redeemedtickets GROUP BY ticketid HAVING COUNT(ticketid) = 1";
我会使用 NOT EXISTS
、NOT IN
或 LEFT JOIN
来解决这个问题。这是后一个版本:
select d.*
from downloadedtickets d left outer join
redeemedtickets r
on d.ticketid = r.ticketid
where r.ticketid is null;
您的查询似乎应该 return 指定的结果。对于您得到的结果(无行)的一种可能解释是没有任何未兑换的已下载门票。
此查询似乎假定 ticketid
在 downloadedtickets
table 中是唯一的,并且在 redeemedtickets
table 中是唯一的...是这样,但我们没有从我们提供的规范中获得该信息。 (如果不是这种情况,那么仅来自 downloadedtickets
table 的 ticketid
的 COUNT(*) 可能大于一个。
ticketid
是用于 "match" 来自两个 table 的行的正确列吗?我们假设它是,因为这就是您的查询所使用的。 (如果不是,那也可以解释您得到的结果。)
您的查询采用以下形式(更容易阅读):
SELECT t.ticketid
FROM ( SELECT d.ticketid
FROM downloadedtickets d
UNION ALL
SELECT r.ticketid
FROM redeemedtickets r
) t
GROUP BY t.ticketid
HAVING COUNT(*) = 1
我们注意到,对于 redeemedtickets
中不在 downloadedtickets
中的行,此查询有可能 return ticketid
。可能有某种保证不会发生这种情况,但同样,规范中没有该信息。
对于大型集合,实现内联视图的成本可能很高。
就个人而言,我更喜欢使用具有更高效 "anti-join" 模式的查询:
SELECT d.ticketid
FROM downloadedtickets d
LEFT
JOIN redeemedtickets r
ON r.ticketid = d.ticketid
WHERE r.ticketid IS NULL
ORDER BY d.ticketid
这实际上是说,return 来自 downloadedtickets
的所有行,以及来自 redeemed
票的任何 "matching" 行。 LEFT
关键字使它成为一个 "outer" 连接,因此我们从左侧的 table 中获取所有行,无论左侧的 table 中是否存在匹配的行右边。诀窍是 WHERE
子句中的谓词,它过滤掉所有匹配的行。 (如果匹配,我们保证 redeemedtickets
中的 ticketid
将是非 NULL。因此,table 中唯一具有 NULL 值的行将是来自downloadedtickets
没有匹配项。
此查询可以有效利用 redeemedtickets
上的索引,其前导列为 ticketid
。
这不是唯一会 return 指定结果的查询,还有其他查询模式可以 return 等效结果。