选择最近的记录。

6
如何选择最近的记录,如果这些记录具有几乎相同的数据...
例如:
col1       col2          col3              col4
--------------------------------------------------
123         abc          1.1               12345
123         abc          1.1               123445
1234        dsv          2.0               123
1234        dsv          2.0               1233
12345       dsvw         1.2               1234

col4与其他列进行比较时,其取最大值。

观察行1和行2的数据,它们看起来相似,但我们需要基于col4获取最新的数据。

同样的,对于行3和行4,数据看起来相似,但我们需要基于col4获取最新的数据。

所需输出结果为:

col1    col2   col3   col4
----------------------------
123     abc    1.1    123445
1234    dsv    2.0    1233
12345   dsvw   1.2    1234 

1
“based on col4” 是什么意思?你是说基于最大的col4值吗?如果第二行的“col2”值为“abcd”,你想要的输出结果会是什么? - Abe Miessler
1
Abe,我也在想同样的问题...答案可能会认为GROUP BY解决方案不合适。 - Aaron Bertrand
如果col2的值不同,整个情景就会有所不同,我将拥有那个列。当所有行除了col4的值相同时,输出将在操作下生成。 - Shahsra
“输出将在操作下进行”是什么意思?您能否在示例中添加另一行,包括不同的col2值,并根据需要修改所需的输出,以便我们理解? - Abe Miessler
抱歉回复晚了。我会编辑我的问题并添加另一行。 - Shahsra
4个回答

5
我假设"latest"的意思是"最新的",对吗?
DECLARE @t TABLE
(
    col1 INT, 
    col2 CHAR(3), 
    col3 DECIMAL(4,1), 
    col4 INT
);

INSERT @t SELECT 123, 'abc', 1.1, 12345
UNION SELECT 123, 'abc', 1.1, 123445
UNION SELECT 1234, 'dsv', 2.0, 123
UNION SELECT 1234, 'dsv', 2.0, 1233;

WITH t AS
(
    SELECT col1, col2, col3, col4,
        rn = ROW_NUMBER() OVER
            (PARTITION BY col1 ORDER BY col4 DESC)
        FROM @t
)
SELECT col1, col2, col3, col4
    FROM t
    WHERE rn = 1;

如果你下次包含DDL和样本数据,也许我会赢。:-) - Aaron Bertrand
什么?CREATE DATABASE语句在哪里?如果你看得够仔细,这个答案里还有一整个厨房水槽 =) - OMG Ponies
我试图通过被动诱导人们在他们的问题中包含它,这样我就不必费力去重现他们的问题。表格输出或结果窗格的屏幕截图并不能帮助我构建样例数据。 :-) - Aaron Bertrand
IME,有时候会碰巧成功。一些人欣赏这种努力。 - OMG Ponies

3

使用:

WITH example AS (
   SELECT t.*,
          ROW_NUMBER() OVER (PARTITION BY t.col1
                                 ORDER BY t.col4 DESC) AS rnk
     FROM YOUR_TABLE t)
SELECT e.*
  FROM example e
 WHERE e.rnk = 1

..或者:

SELECT e.*
  FROM (SELECT t.*,
               ROW_NUMBER() OVER (PARTITION BY t.col1
                                      ORDER BY t.col4 DESC) AS rnk
          FROM YOUR_TABLE t) e
 WHERE e.rnk = 1

CTE并没有提供比派生表方法更好的优化。

0

这个可以实现你想要的功能:

select * from table t
where col4 = (select max(col4) from table where col1 = t.col1);

如果需要(问题描述不太清楚),您可以根据需要向测试中添加其他列,例如:

select * from table t
where col4 = (select max(col4) from table
              where col1 = t.col1 and col2 = t.col2 and col3 = t.col3);

注意:如果有多个记录共享 col4 的最大值,则会返回多个行。这可能不是问题,或者您可以根据需要使用 DISTINCT 或其他处理方式。

这样做的潜在问题是col4的值可能会重复,因此它不会返回不同的行。这就像使用DENSE_RANK函数一样... - OMG Ponies

-1

我觉得其他答案可能让我错过了什么,但在我看来,这只是一个简单的MAX/group by

with temp as
(
select 123 as col1,'abc' as col2, '1.1' as col3, 12345 as col4
UNION
select 123, 'abc', '1.1'  ,123445
UNION
select 1234,'dsv','2.0' ,123
UNION
select 1234,'dsv' ,'2.0'  ,1233

)

SELECT col1, Col2, COl3, MAX(Col4)
FROM temp
GROUP BY col1, col2,col3

这将返回您想要的结果


不行。这样做不能为每个col1值返回单独的一行 - 请参见问题中的预期结果。 - Bohemian
我刚刚运行了上面的查询,它成功了。这与他所提供的样本数据集有关吗?我感觉自己漏掉了什么,但我不确定是什么... - Abe Miessler
如果在给定的col1行中,col2和col3有所不同,那么从问题描述中无法确定(但如果它们没有变化,数据几乎没有用处),在这种情况下,您的查询将无法正常工作。 - Bohemian
我同意如果数据不同,则不能正常工作。我也同意从问题中并不清楚。在获得澄清之前,我不能说这不是他想要的。 - Abe Miessler
这句话“当它与其他列进行比较时,col4的最大值。”虽然不太清楚,但也让我想到这可能是他要找的。 - Abe Miessler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接