SQL左联接:选择一对多关系中的最后记录
我有一张客户表和一张明细表 我想为表中的每个客户提取一条记录,并在适用的情况下显示该客户的最新详细数据 目前我的where子句正在筛选出客户 我已经尝试将where子句移动到左侧外部联接中,但未能获得所需的结果 当我运行查询时,它似乎根本不会过滤产品SQL左联接:选择一对多关系中的最后记录,sql,join,greatest-n-per-group,advantage-database-server,Sql,Join,Greatest N Per Group,Advantage Database Server,我有一张客户表和一张明细表 我想为表中的每个客户提取一条记录,并在适用的情况下显示该客户的最新详细数据 目前我的where子句正在筛选出客户 我已经尝试将where子句移动到左侧外部联接中,但未能获得所需的结果 当我运行查询时,它似乎根本不会过滤产品 SELECT cust.Customer , cust.Company , inv.Date , inv.Product , inv.Units , inv.Extended FROM customerlist c
SELECT
cust.Customer
, cust.Company
, inv.Date
, inv.Product
, inv.Units
, inv.Extended
FROM
customerlist cust
LEFT OUTER JOIN
detail inv
ON
cust.customer = inv.customer
LEFT OUTER JOIN
detail inv2
ON
inv.customer = inv2.customer
AND (
inv.date < inv2.date
OR inv.date = inv2.date AND inv.customer < inv2.customer
)
WHERE
(
inv.Product = 'CC'
OR inv.Product = 'CG'
OR inv.Product = 'CH'
)
AND inv2.customer IS NULL
选择
客户
,客户公司
,投资日期
,库存产品
,存货单位
,投资扩展
从…起
定制客户
左外连接
详细信息
在…上
客户=库存客户
左外连接
详细信息inv2
在…上
inv.customer=inv2.customer
及(
库存日期<库存日期
或inv.date=inv2.date,inv.customer
我的问题类似于
我在尝试同样的事情,只是想包括每个客户和过滤器的产品
更新
样本数据 这是我的原始查询,非常好,只是我缺少客户 如果我删除where子句并将其插入左连接,如下所示
LEFT OUTER JOIN
detail inv2
ON
inv.customer = inv2.customer
AND (
inv.date < inv2.date
OR inv.date = inv2.date AND inv.customer < inv2.customer
)
AND (
inv.Product = 'CC'
OR inv.Product = 'CHECK'
OR inv.Product = 'ACH'
)
左外连接
详细信息inv2
在…上
inv.customer=inv2.customer
及(
库存日期<库存日期
或inv.date=inv2.date,inv.customer
结果如下
显示的产品列不是“CC”等。。而且客户是重复的
您的第二次
左键加入
意味着在客户最近一次加入之前排除订单?我会重写它,因为存在。我不熟悉Advantage数据库,希望它的SQL实现并不罕见
SELECT
Cust.Customer,
Cust.Company,
Inv.Date,
Inv.Product,
Inv.Units,
Inv.Extended
FROM
customerlist AS Cust
LEFT JOIN detail AS Inv ON Cust.customer = Inv.customer
WHERE
(Inv.Product = 'CC' OR Inv.Product = 'CG' OR Inv.Product = 'CH')
AND NOT EXISTS (SELECT * FROM detail AS Inv2 WHERE Cust.customer = Inv2.customer AND Inv2.date > inv.date)
假设Advantage支持
中的
,则可以通过将X='A'或X='B'替换为中的X来简化
SELECT
cust.Customer
, cust.Company
, inv.Date
, inv.Product
, inv.Units
, inv.Extended
FROM
customerlist cust
LEFT OUTER JOIN
detail inv
ON
cust.customer = inv.customer
AND inv.Product IN ('CC', 'CG', 'CH')
LEFT OUTER JOIN
detail inv2
ON
inv.customer = inv2.customer
AND (
inv.date < inv2.date
OR inv.date = inv2.date AND inv.customer < inv2.customer
)
WHERE
inv2.customer IS NULL
请注意,如前所述,这表明客户的最新订单类型为“CC”、“CG”或“CH”。如果目标是显示客户该类型的最新订单,即使他们有另一类型的后续订单,也需要进行调整
例如,如果Bob购买了AB、BC、CC和DE,他将被排除在上述查询之外。如果你想包括他,因为他购买了CC产品,尽管他后来购买了DE,请发表评论,我将演示如何操作。你的第二次
左加入是为了在客户最近的一次加入之前排除订单?我会重写它,因为存在。我不熟悉Advantage数据库,希望它的SQL实现并不罕见
SELECT
Cust.Customer,
Cust.Company,
Inv.Date,
Inv.Product,
Inv.Units,
Inv.Extended
FROM
customerlist AS Cust
LEFT JOIN detail AS Inv ON Cust.customer = Inv.customer
WHERE
(Inv.Product = 'CC' OR Inv.Product = 'CG' OR Inv.Product = 'CH')
AND NOT EXISTS (SELECT * FROM detail AS Inv2 WHERE Cust.customer = Inv2.customer AND Inv2.date > inv.date)
假设Advantage支持
中的
,则可以通过将
X='A'或X='B'替换为中的X来简化
SELECT
cust.Customer
, cust.Company
, inv.Date
, inv.Product
, inv.Units
, inv.Extended
FROM
customerlist cust
LEFT OUTER JOIN
detail inv
ON
cust.customer = inv.customer
AND inv.Product IN ('CC', 'CG', 'CH')
LEFT OUTER JOIN
detail inv2
ON
inv.customer = inv2.customer
AND (
inv.date < inv2.date
OR inv.date = inv2.date AND inv.customer < inv2.customer
)
WHERE
inv2.customer IS NULL
请注意,如前所述,这表明客户的最新订单类型为“CC”、“CG”或“CH”。如果目标是显示客户该类型的最新订单,即使他们有另一类型的后续订单,也需要进行调整
例如,如果Bob购买了AB、BC、CC和DE,他将被排除在上述查询之外。如果你想把他包括进来,因为他买了CC产品,尽管他后来买了DE,请评论,我会告诉你怎么做。你几乎做对了 您的第一个查询将删除所有没有指定产品详细信息的客户,因为您没有在第一个
外部联接的ON
条件中指定产品筛选器
SELECT
cust.Customer
, cust.Company
, inv.Date
, inv.Product
, inv.Units
, inv.Extended
FROM
customerlist cust
LEFT OUTER JOIN
detail inv
ON
cust.customer = inv.customer
AND inv.Product IN ('CC', 'CG', 'CH')
LEFT OUTER JOIN
detail inv2
ON
inv.customer = inv2.customer
AND (
inv.date < inv2.date
OR inv.date = inv2.date AND inv.customer < inv2.customer
)
WHERE
inv2.customer IS NULL
你几乎说对了
您的第一个查询将删除所有没有指定产品详细信息的客户,因为您没有在第一个外部联接的ON
条件中指定产品筛选器
SELECT
cust.Customer
, cust.Company
, inv.Date
, inv.Product
, inv.Units
, inv.Extended
FROM
customerlist cust
LEFT OUTER JOIN
detail inv
ON
cust.customer = inv.customer
AND inv.Product IN ('CC', 'CG', 'CH')
LEFT OUTER JOIN
detail inv2
ON
inv.customer = inv2.customer
AND (
inv.date < inv2.date
OR inv.date = inv2.date AND inv.customer < inv2.customer
)
WHERE
inv2.customer IS NULL
是否可以这样做:并且inv2.customer为空您使用的是什么RDM(Sql server、mysql、oracel)?您可以发布一些示例数据吗?Advantage DataBase server 9.1我的更新帮助与示例数据有关吗?如果有什么我可以做的,让它更清楚,让我知道。谢谢你的帮助!是否可以这样做:并且inv2.customer为空您使用的是什么RDM(Sql server、mysql、oracel)?您可以发布一些示例数据吗?Advantage DataBase server 9.1我的更新帮助与示例数据有关吗?如果有什么我可以做的,让它更清楚,让我知道。谢谢你的帮助!这并不能解决缺少客户的问题,Trevor希望结果中的每个客户都有行,即使是那些没有找到相应细节的客户,如果我理解正确的话。@JensMühlenhoff:嗯,你可能是对的。如果是这样的话,我不知道第二个左连接的OP意味着什么。看起来你在正确的轨道上,希望你能让OP实现他的目标。你读过相关的问题了吗?OP似乎从接受的答案中选择了第二个左连接
和WHERE IS NULL
概念,但混淆了ON
条件中的字段。这并不能解决缺少客户的问题,Trevor希望在结果中为每个客户指定行,即使是那些没有找到相应详细信息的客户,如果我理解正确的话。@JensMühlenhoff:嗯,你可能是对的。如果是这样的话,我不知道第二个左连接的OP意味着什么。看起来你在正确的轨道上,希望你能让OP实现他的目标。你读过相关的问题了吗?OP似乎从接受的答案中选择了第二个左连接
和WHERE IS NULL
概念,但混淆了ON
条件中的字段。观察良好