相关子查询:如何获取外部查询的ID?
Correlated subqueries: How to get the ID of the outer query?
我有多个表:
Person
---------------------
IDPerson, Name
StickerTransaction
---------------------
IDTransac, IDPerson, IDSomeoneElse, NbStickersReceived, NbStickersGiven
Purchase
---------------------
IDPurchase, IDPerson, NbStickersBought
我正在尝试让每个从未进行过交易或目前拥有 0 个贴纸的人都参与进来。要获得一个人拥有的贴纸数量,请使用以下公式:
NbStickersBought + NbStickersReceived - NbStickersGiven
这是我目前收到的查询。我遇到的问题是在 subsubsubqueries 中...我无权访问此人的 ID。
有没有办法访问此人的 ID 或者是否有更好的方法来编写此查询?
SELECT People.IDPerson, People.Name
FROM
(
-- Selects people that never made a sticker transaction
SELECT p.IDPerson, p.Name
FROM Person p
LEFT JOIN StickerTransaction sT
ON p.IDPerson = sT.IDPerson
WHERE sT.IDPerson IS NULL
UNION
-- Selects people that have currently 0 sticker
SELECT p.IDPerson, p.Name
FROM Person p
WHERE 0 = (
SELECT SUM(NbStickers) AS NbStickers
FROM (
-- I do not have access to p.IDPerson here...
SELECT (sT.NbStickersReceived - sT.NbStickersGiven) AS NbStickers
FROM StickerTransaction sT
WHERE sT.IDPerson = p.IDPerson
UNION ALL
-- I do not have access to p.IDPerson here either...
SELECT pu.NbStickersBought AS NbStickers
FROM Purchase pu
WHERE pu.IDPerson = p.IDPerson
)
)
) People
SELECT People.IDPerson, People.Name
FROM Person
where IDPerson not in
(select distinct IDPerson from StickerTransaction)
and IDPerson not in
(SELECT IDPerson from Purchase group by IDPerson having SUM(NbStickers) > 0)
据我所知,您不能对派生 Table 进行关联。但是您可以将查询重写为不相关的子查询:
SELECT People.IDPerson, People.NAME
FROM
(
-- Selects people that never made a sticker transaction
SELECT p.IDPerson, p.NAME
FROM Person p
LEFT JOIN StickerTransaction sT
ON p.IDPerson = sT.IDPerson
WHERE sT.IDPerson IS NULL
UNION
-- Selects people that have currently 0 sticker
SELECT p.IDPerson, p.NAME
FROM Person p
JOIN (
SELECT sT.IDPerson, SUM(NbStickers) AS NbStickers
FROM (
SELECT (sT.NbStickersReceived - sT.NbStickersGiven) AS NbStickers
FROM StickerTransaction sT
UNION ALL
SELECT pu.NbStickersBought AS NbStickers
FROM Purchase pu
) dt
GROUP BY sT.IDPerson
HAVING SUM(NbStickers) = 0
) sT
ON sT.IDPerson = p.IDPerson
) People
使用 NOT EXISTS
查找从未购买过的人。
使用另一个子查询来查找那些拥有与 NbStickersGiven 相同数量的 NbStickersReceived。
SELECT p.IDPerson, p.Name
FROM Person p
where not exists (select 1 from Purchase
where IDPerson = p.IDPerson)
or 0 = (select sum(NbStickersReceived) - sum(NbStickersGiven)
from StickerTransaction
where IDPerson = p.IDPerson)
也许您需要 COALESCE
第二个子查询,以处理没有任何 StickerTransactions 的人。
您必须在外部语句中创建 link。
-- Selects people that have currently 0 sticker
SELECT p.IDPerson, p.Name
FROM Person p,
(SELECT sT.IDPerson, SUM(NbStickers) sum_stickers
FROM ((SELECT sT.IDPerson, (sT.NbStickersReceived - sT.NbStickersGiven) AS NbStickers
FROM StickerTransaction sT)
UNION
(SELECT pu.IDPerson, pu.NbStickersBought AS NbStickers
FROM PURCHASE pu
))
group by sT.IDPerson
) zeroSticker
where zeroSticker.IDPerson = p.IDPerson and zeroSticker.sum_stickers = 0
因为在普通 SQL 中不可能将参数注入子查询。
我有多个表:
Person
---------------------
IDPerson, Name
StickerTransaction
---------------------
IDTransac, IDPerson, IDSomeoneElse, NbStickersReceived, NbStickersGiven
Purchase
---------------------
IDPurchase, IDPerson, NbStickersBought
我正在尝试让每个从未进行过交易或目前拥有 0 个贴纸的人都参与进来。要获得一个人拥有的贴纸数量,请使用以下公式:
NbStickersBought + NbStickersReceived - NbStickersGiven
这是我目前收到的查询。我遇到的问题是在 subsubsubqueries 中...我无权访问此人的 ID。
有没有办法访问此人的 ID 或者是否有更好的方法来编写此查询?
SELECT People.IDPerson, People.Name
FROM
(
-- Selects people that never made a sticker transaction
SELECT p.IDPerson, p.Name
FROM Person p
LEFT JOIN StickerTransaction sT
ON p.IDPerson = sT.IDPerson
WHERE sT.IDPerson IS NULL
UNION
-- Selects people that have currently 0 sticker
SELECT p.IDPerson, p.Name
FROM Person p
WHERE 0 = (
SELECT SUM(NbStickers) AS NbStickers
FROM (
-- I do not have access to p.IDPerson here...
SELECT (sT.NbStickersReceived - sT.NbStickersGiven) AS NbStickers
FROM StickerTransaction sT
WHERE sT.IDPerson = p.IDPerson
UNION ALL
-- I do not have access to p.IDPerson here either...
SELECT pu.NbStickersBought AS NbStickers
FROM Purchase pu
WHERE pu.IDPerson = p.IDPerson
)
)
) People
SELECT People.IDPerson, People.Name
FROM Person
where IDPerson not in
(select distinct IDPerson from StickerTransaction)
and IDPerson not in
(SELECT IDPerson from Purchase group by IDPerson having SUM(NbStickers) > 0)
据我所知,您不能对派生 Table 进行关联。但是您可以将查询重写为不相关的子查询:
SELECT People.IDPerson, People.NAME
FROM
(
-- Selects people that never made a sticker transaction
SELECT p.IDPerson, p.NAME
FROM Person p
LEFT JOIN StickerTransaction sT
ON p.IDPerson = sT.IDPerson
WHERE sT.IDPerson IS NULL
UNION
-- Selects people that have currently 0 sticker
SELECT p.IDPerson, p.NAME
FROM Person p
JOIN (
SELECT sT.IDPerson, SUM(NbStickers) AS NbStickers
FROM (
SELECT (sT.NbStickersReceived - sT.NbStickersGiven) AS NbStickers
FROM StickerTransaction sT
UNION ALL
SELECT pu.NbStickersBought AS NbStickers
FROM Purchase pu
) dt
GROUP BY sT.IDPerson
HAVING SUM(NbStickers) = 0
) sT
ON sT.IDPerson = p.IDPerson
) People
使用 NOT EXISTS
查找从未购买过的人。
使用另一个子查询来查找那些拥有与 NbStickersGiven 相同数量的 NbStickersReceived。
SELECT p.IDPerson, p.Name
FROM Person p
where not exists (select 1 from Purchase
where IDPerson = p.IDPerson)
or 0 = (select sum(NbStickersReceived) - sum(NbStickersGiven)
from StickerTransaction
where IDPerson = p.IDPerson)
也许您需要 COALESCE
第二个子查询,以处理没有任何 StickerTransactions 的人。
您必须在外部语句中创建 link。
-- Selects people that have currently 0 sticker
SELECT p.IDPerson, p.Name
FROM Person p,
(SELECT sT.IDPerson, SUM(NbStickers) sum_stickers
FROM ((SELECT sT.IDPerson, (sT.NbStickersReceived - sT.NbStickersGiven) AS NbStickers
FROM StickerTransaction sT)
UNION
(SELECT pu.IDPerson, pu.NbStickersBought AS NbStickers
FROM PURCHASE pu
))
group by sT.IDPerson
) zeroSticker
where zeroSticker.IDPerson = p.IDPerson and zeroSticker.sum_stickers = 0
因为在普通 SQL 中不可能将参数注入子查询。