选择多个唯一类别ID的最新条目

时间:2018-08-10 03:09:14

标签: mysql sql select min

Skipping optional fixer: buffer
    Skipping optional fixer: idioms
    Skipping optional fixer: set_literal
    Skipping optional fixer: ws_comma
    running build_ext
    building '_cvxcore' extension
    error: [WinError 3] The system cannot find the path specified: 'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\PlatformSDK\\lib'

您好,我正在尝试从具有这种结构的表中选择信息。我需要从所有rootID返回类别1中的所有行,但仅在editDate为null的情况下,并且还从每个rootID返回min(createdDate)。

我希望得到第2、5和7行的结果。但是,如果将ID [4]的editDate值替换为NULL,则必须为rootID 3返回ID 4,而不是5。 >

我一直在寻找类似的帖子,我发现的最接近的帖子是: SQL MIN Function with where clause

我觉得我与在其中找到的示例之一很接近,但是它们正在使用两个表,而我只需要使用这个表。这是我现在正在尝试的内容:

Table Name: entries
ID (int)
rootID (int) 
categoryID (int)
editDate (dateTime [ default null ])
createdDate (dateTime [ default NOW() ]) 

  +--+--------+----------+---------------------+---------------------+
  |ID| rootID |categoryID|       editDate      |     createdDate     |
  +--+--------+----------+---------------------+---------------------+
  | 1|    1   |     1    | 2018-05-02 18:59:01 | 2018-04-01 18:52:37 | 
  | 2|    1   |     1    |        null         | 2018-05-02 18:59:01 |
  | 3|    3   |     1    | 2018-06-10 19:32:01 | 2018-06-10 19:12:01 |
  | 4|    3   |     1    | 2018-07-11 18:52:01 | 2018-06-10 19:32:01 |
  | 5|    3   |     1    |        null         | 2018-07-11 18:52:01 |
  | 6|    6   |     1    | 2018-10-09 12:38:01 | 2018-10-09 12:27:01 |
  | 7|    6   |     1    |        null         | 2018-10-09 12:38:01 |
  | 8|    8   |     2    | 2018-11-09 08:12:11 | 2018-12-09 10:12:01 |
  | 9|    8   |     2    |        null         | 2018-11-09 08:12:11 |
  +--+--------+----------+---------------------+---------------------+

但是,这仅从第一个rootID的最早创建日期起返回一个条目。我在理解查询时遇到了麻烦,但是我开始看到它仅是指一个条目。

我要寻找的是来自categoryID = 1,找到每个不同rootID的ID,它们的创建日期最早,行的编辑日期为NULL。如何更改此值以从每个根返回一个?谢谢大家的宝贵时间。我将继续发布今晚尝试的SQL。

3 个答案:

答案 0 :(得分:2)

您的示例的问题在于,它只选择了createdDate与整个表中一个最小的createdDate相匹配的行。这就是SELECT min(createdDate)FROM条目所要做的,仅返回一个createdDate。

我认为您需要做的是找到一种方法,为每个给定的rootId选择最小的createdDate。我会尝试这样的事情:

SELECT *
  FROM entries A
 WHERE A.categoryId = 1
   AND A.editDate IS NULL
   AND A.createdDate = (SELECT MIN(B.createdDate)
                          FROM entries B
                         WHERE A.rootId     = B.rootId
                           AND B.categoryId = 1
                           AND B.editDate  IS NULL);

这样,您从categoryId为1的表中选择,editDate为null,并且createdDate匹配categoryId = 1,editDate为null的所有行的最小createdDate,以及与rootId匹配的所有行。外部查询正在查看的行。

答案 1 :(得分:1)

我想你想要这个:

SELECT *
FROM entries A
WHERE Id IN (
    SELECT Id
    FROM entries B
    WHERE A.rootId = B.rootId
    AND A.categoryId = B.categoryId
    AND B.editDate IS NULL
    AND categoryId = 1
    AND A.createdDate = B.createdDate
)
GROUP BY rootId, categoryId
HAVING createdDate = MIN(createdDate)

答案 2 :(得分:1)

这同时适用于SQL Server和MySQL

SELECT e.*
 FROM 
 (
    SELECT rootID, MIN(CASE WHEN editDate IS NULL THEN ID ELSE NULL END) AS editDateId, MIN(createdDate) AS minCreatedDate
    FROM entries
    WHERE categoryID = 1
    GROUP BY rootID
  ) t
  JOIN  entries e
  ON    e.ID = (case when t.editDateId IS NOT NULL THEN editDateId END) OR
        (t.editDateId IS NULL AND createdDate = t.minCreatedDate)