【问题标题】:How to get rows from two tables on maximum value of particular field如何从两个表中获取特定字段最大值的行
【发布时间】:2018-11-28 02:57:20
【问题描述】:

我有两个具有date_updated 列的表。

TableA 如下所示

 con_id         date_updated         type     
--------------------------------------------
123              19/06/2018          2
123              15/06/2018          1     
123              01/05/2018          3  
101              06/04/2018          1
101              05/03/2018          2 

我有 TableB 也有相同的结构

 con_id         date_updated         type     
--------------------------------------------
123              15/05/2018          2  
123              01/05/2018          1  
101              07/06/2018          1

结果表应该有最近日期的数据

 con_id         date_updated         type     
--------------------------------------------
123              19/06/2018          2
101              07/06/2018          1  

这里date_updated列是sql server的datetime数据类型。我尝试使用group by 并选择最大date_updated。但我无法在select 语句中包含列类型。当我在group by 中使用类型时,结果不正确,因为类型也被分组。我该如何查询这个。请帮忙

【问题讨论】:

  • ,不是字段。

标签: sql sql-server group-by groupwise-maximum


【解决方案1】:
SELECT *
FROM
    (SELECT *, ROW_NUMBER() OVER(Partition By con_id ORDER BY date_updated DESC) as seq
     FROM
        (SELECT * FROM TableA
        UNION ALL
        SELECT * FROM TableB) as tblMain) as tbl2
WHERE seq = 1

【讨论】:

  • as seq 从哪里来??哪个表??您需要在此处添加FROM
  • tblMain 是两个表的并集,tbl2 是带有名为 seq 的附加列的 tblmain。谢谢我编辑了它
【解决方案2】:

一种方法:

WITH A AS(
    SELECT TOP 1 con_id,
                 date_updated,
                 type
    FROM TableA
    ORDER BY date_updated DESC),
B AS(
    SELECT TOP 1 con_id,
                 date_updated,
                 type
    FROM TableB
    ORDER BY date_updated DESC),
U AS(
    SELECT *
    FROM A
    UNION ALL
    SELECT *
    FROM B)
SELECT *
FROM U;

顶部的 2 个 CTE 从表中获取您最近的行,然后 end 语句将它们合并在一起。

为了那些说这不起作用的人的利益:

USE Sandbox;
GO

CREATE TABLE tablea (con_id int, date_updated date, [type] tinyint);
CREATE TABLE tableb (con_id int, date_updated date, [type] tinyint);
GO

INSERT INTO tablea 
VALUES
(123,'19/06/2018',2),
(123,'15/06/2018',1),     
(123,'01/05/2018',3),  
(101,'06/04/2018',1),
(101,'05/03/2018',2); 

INSERT INTO tableb
VALUES
(123,'15/05/2018',2),  
(123,'01/05/2018',1), 
(101,'07/06/2018',1);
GO
WITH A AS(
    SELECT TOP 1 con_id,
                 date_updated,
                 [type]
    FROM TableA
    ORDER BY date_updated DESC),
B AS(
    SELECT TOP 1 con_id,
                 date_updated,
                 [type]
    FROM TableB
    ORDER BY date_updated DESC),
U AS(
    SELECT *
    FROM A
    UNION ALL
    SELECT *
    FROM B)
SELECT *
FROM U;

GO
DROP TABLE tablea;
DROP TABLE tableb;

这将返回数据集:

con_id      date_updated type
----------- ------------ ----
123         2018-06-19   2
101         2018-06-07   1

这与 OP 的数据相同:

 con_id         date_updated         type     
--------------------------------------------
123              19/06/2018          2
101              07/06/2018          1  

【讨论】:

  • 感谢您的回答。但是我必须使用 con_id 将此 select 语句与另一个表连接起来。以 WITH 开头是否可以加入查询。
  • 是的,将 UNION 查询放在另一个 CTE 中。
  • 这个查询没有给出预期的结果。你可能想用一些数据来试运行它。您获得了 date_updated 列的表顶部,但缺少基于 con_id 的分组。
  • @AmithKumar 这不是 OP 的样本数据。
  • 是的,但是 OP 说他需要按con_id 分组。如果有两个以上 con_id 或两个表都具有相同 con_id 的最新信息,则提供的查询将忽略另一个 con_ids。
【解决方案3】:

希望这会有所帮助:

WITH combined 
     AS( 
select * FROM tableA 
UNION 
select * FROM tableB) 

SELECT t1.con_id, 
       t1.date_updated, 
       t1.type 
FROM  ( 
                SELECT   con_id, 
                         date_updated, 
                         type, 
                         row_number() OVER(partition BY con_id ORDER BY date_updated DESC) AS rownumber
                FROM     combined) t1 
WHERE  rownumber = 1;

【讨论】:

  • 那行不通,ORDER BY 必须在所有UNION 之后。例如,尝试SELECT 1 AS i ORDER BY i UNION SELECT 2 AS i ORDER BY i;。你会得到一个语法错误。
  • 是的,完全错过了。
【解决方案4】:

可以使用窗口函数来完成:

declare @TableA table (con_id int, date_updated date, [type] int)
declare @TableB table (con_id int, date_updated date, [type] int)

insert into @TableA values
  (123, '2018-06-19', 2)
, (123, '2018-06-15', 1)     
, (123, '2018-05-01', 3)  
, (101, '2018-04-06', 1)
, (101, '2018-03-05', 2) 

insert into @TableB values
  (123, '2018-05-15', 2)  
, (123, '2018-05-01', 1)  
, (101, '2018-06-07', 1)

select distinct con_id
    , first_value(date_updated) over (partition by con_id order by con_id, date_updated desc) as con_id
    , first_value([type]) over (partition by con_id order by con_id, date_updated desc) as [type]
from
(Select * from @TableA UNION Select * from @TableB) x

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-14
    • 2016-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多