如何构建查询以获取每个用户的最新行,其中第三个条件位于单独的表中?

Posted

技术标签:

【中文标题】如何构建查询以获取每个用户的最新行,其中第三个条件位于单独的表中?【英文标题】:How do I build a query to get the latest row per user where a third criteria is in a separate table? 【发布时间】:2021-09-08 21:00:18 【问题描述】:

我有三张桌子

CREATE TABLE `LineItems` (
  `LineItemID` int NOT NULL,
  `OrderID` int NOT NULL,
  `ProductID` int NOT NULL
);


INSERT INTO `LineItems` (`LineItemID`, `OrderID`, `ProductID`) VALUES
(1, 1, 2),
(2, 1, 1),
(3, 2, 3),
(4, 2, 4),
(5, 3, 1),
(6, 4, 2),
(7, 5, 4),
(8, 5, 2),
(9, 5, 3),
(10, 6, 1),
(11, 6, 4),
(12, 7, 4),
(13, 7, 1),
(14, 7, 2),
(15, 8, 1),
(16, 9, 3),
(17, 9, 4),
(18, 10, 3);


CREATE TABLE `Orders` (
  `OrderID` int NOT NULL,
  `UserID` int NOT NULL,
  `OrderDate` datetime NOT NULL
);

INSERT INTO `Orders` (`OrderID`, `UserID`, `OrderDate`) VALUES
(1, 21, '2021-05-01 00:00:00'),
(2, 21, '2021-05-03 00:00:00'),
(3, 24, '2021-05-06 00:00:00'),
(4, 23, '2021-05-12 00:00:00'),
(5, 21, '2021-05-14 00:00:00'),
(6, 22, '2021-05-16 00:00:00'),
(7, 23, '2021-05-20 00:00:00'),
(8, 21, '2021-05-22 00:00:00'),
(9, 24, '2021-05-23 00:00:00'),
(10, 23, '2021-05-26 00:00:00');

CREATE TABLE `Products` (
  `ProductID` int NOT NULL,
  `ProductTitle` VARCHAR(250) NOT NULL,
  `ProductType` enum('doors','windows','flooring') NOT NULL
);


INSERT INTO `Products` (`ProductID`, `ProductTitle`, `ProductType`) VALUES
(1, 'French Doors','doors'),
(2, 'Sash Windows','windows'),
(3, 'Sliding Doors','doors'),
(4, 'Parquet Floor','flooring');

SQL Fiddle:

Orders - 包含订单日期和用户 ID

LineItems - 订单表的外键,包含订单中的产品 ID

Products - 包含产品的详细信息(包括它们是门、窗还是地板)

我已经弄清楚如何使用

获取每个用户的最新订单
SELECT O.* FROM Orders O LEFT JOIN Orders O2 
  ON O2.UserID=O.UserID AND O.OrderDate < O2.OrderDate 
WHERE O2.OrderDate IS NULL;

这很好用,并且包含在 SQL 小提琴中,以及一个返回完整图片以供参考的查询。

我正试图弄清楚如何为每位用户获取最新的地板订单,但我没有任何运气。

在上面链接的 SQL 小提琴中,我所追求的预期输出将是

OrderID | UserID | OrderDate
6       | 22     | 2021-05-16T00:00:00Z
5       | 21     | 2021-05-14T00:00:00Z
9       | 24     | 2021-05-23T00:00:00Z
7       | 23     | 2021-05-20T00:00:00Z

编辑:为了澄清,在预期结果中,两行(对于用户 21 和 23)与仅获取每个用户最新订单的查询不同。这是因为订单 ID 8 和 10(来自每个用户查询的最新订单)不包括地板。预期的查询必须从每个用户那里找到最新的带地板的订单,才能在结果集中返回。

【问题讨论】:

你试过“order by OrderDate desc;” @Jethan - 我不明白这将如何帮助或我将它放在哪里。 【参考方案1】:

您需要将 LineItems 和 Products 表添加到查询中,以查找购买地板的订单:

SELECT DISTINCT O.*
  FROM Orders O
  LEFT JOIN Orders O2 
    ON O2.UserID=O.UserID AND
       O.OrderDate < O2.OrderDate
  INNER JOIN LineItems i
    ON i.OrderID = O.OrderID
  INNER JOIN Products p
    ON p.ProductID = i.ProductID
  WHERE O2.OrderDate IS NULL AND
        p.ProductType = 'flooring'

db<>fiddle here

【讨论】:

该查询的结果与预期结果不匹配 - 用户 ID 5 和 7 未包含在结果集中。 嗯,这就是一般的想法。您可以从那里对其进行细化。 另外,您的原始查询不会返回 UserID 5 和 7 的任何数据。 哇,我完全输入了错误字段中的值,只是注意到了。我的意思是 UserID 21 和 23(OrderID 5 和 7)不在您查询的结果集中,但应该符合预期结果。 您的原始查询返回的UserID 21 与OrderID 8 匹配,UserId23 与OrderID 10 匹配。我认为您的原始查询有问题。

以上是关于如何构建查询以获取每个用户的最新行,其中第三个条件位于单独的表中?的主要内容,如果未能解决你的问题,请参考以下文章

查询以获取不为空且不匹配字符串的最新构建说明

优化 GROUP BY 查询以检索每个用户的最新行

如何编写 hql 查询或条件查询以根据时间戳获取最新记录

查询以获取最新的三个用户,按日期排序-Mongoose Node.js

如何在第三个查询中包含来自其他两个表的过滤行数?

如何按日期返回每个字段的最新行