【问题标题】:SQL Join one-to-many tables, selecting only most recent entriesSQL Join 一对多表,只选择最近的条目
【发布时间】:2016-06-07 22:26:32
【问题描述】:

这是我的第一篇文章,如果发错了,我深表歉意!

我正在使用它们各自的 ID 号连接两个具有一对多关系的表:但我只想返回连接表的最新记录,我什至不完全确定从哪里开始!

我返回一切的原始代码如下所示:

SELECT table_DATES.[date-ID], *
FROM table_CORE LEFT JOIN table_DATES ON [table_CORE].[core-ID] =     table_DATES.[date-ID]
WHERE table_CORE.[core-ID] Like '*'
ORDER BY [table_CORE].[core-ID], [table_DATES].[iteration];

这会返回一组记录:显示 table_CORE 和 table_DATES 之间的每个匹配 ID:

table_CORE date-ID iteration
1   1   1
1   1   2
1   1   3
2   2   1
2   2   2
3   3   1
4   4   1

但我只需要返回“迭代”字段中最大值的日期,如下所示

table_CORE date-ID iteration  Additional data
1   1   3    MoreInfo
2   2   2    MoreInfo
3   3   1    MoreInfo
4   4   1    MoreInfo

我真的不知道从哪里开始 - 显然这将是一个 some 排序的 JOIN 查询 - 但我不确定如何让子查询只返回最高迭代表 2 的 ID 字段中的每个项目?

希望这是有道理的 - 如果涉及到它,我会重新措辞!

--编辑-- 我想知道当我需要表 1 中的所有字段(在本例中为 table_CORE)以及表 2 中的所有字段(table_DATES)也加入时如何集成它?

两个表都有需要合并的附加字段。

我很确定我可以将字段添加到“SELECT”和“GROUP BY”子句中,但总共有大约 40 个字段(输入所有字段会很乏味!)

【问题讨论】:

  • 感谢大家的帮助!我已经把原型的最后期限提前了(两个月)——这意味着我需要在我去度假之前把数据库的原型拿出来……那就是明天……我将离开日期分组直到我从假期回来 - 但与此同时,谢谢大家!等我回来再恢复线程!

标签: sql-server tsql


【解决方案1】:

尝试使用带有 GROUP BY 子句的 MAX 聚合函数。

SELECT 
    [ID1],
    [ID2], 
    MAX([iteration])
FROM 
    table_CORE 
    LEFT JOIN table_DATES 
        ON [table_CORE].[core-ID] = table_DATES.[date-ID]
WHERE 
    table_CORE.[core-ID] Like '*' --LIKE '%something%' ??
GROUP BY
    [ID1],
    [ID2]

您的示例字段名称与您的示例查询不匹配,所以我猜测了一下。

【讨论】:

  • 可能也值得使用表别名,它们在 select 或 group by 中并不明确。
  • @PaulAndrew Lol - 我忘记了 WHERE 子句的存在 - VBA 编译时的遗物。当我在两个表中都包含其他字段(大约 40 个!)时,我正在努力使您的方法发挥作用 - 原始问题已更新以反映
【解决方案2】:

为了确保我得到你所要求的一切正确,我将重申你的一些问题,然后回答它。

您的源表如下所示:

table_core:

table_dates:

你的输出是这样的:

当前:

期望:

为了实现这一点,您需要做的就是使用子查询(或CTE)作为“交叉引用”表。 (我使用临时表重新创建了您的数据示例,并用_ 代替了列名中的-)。

--Loading the example data
create table #table_core
    (
        core_id int not null
    )

create table #table_dates
    (
        date_id int not null
        , iteration int not null
        , additional_data varchar(25) null
    )

insert into #table_core values (1), (2), (3), (4)

insert into #table_dates values (1,1, 'More Info 1'),(1,2, 'More Info 2'),(1,3, 'More Info 3'),(2,1, 'More Info 4'),(2,2, 'More Info 5'),(3,1, 'More Info 6'),(4,1, 'More Info 7')

--select query needed for desired output (using a CTE)
; with iter_max as 
    (
        select td.date_id
        , max(td.iteration) as iteration_max
        from #table_dates as td
        group by td.date_id
    )
select tc.*
, td.*
from #table_core as tc
left join iter_max as im on tc.core_id = im.date_id
inner join #table_dates as td on im.date_id = td.date_id
                             and im.iteration_max = td.iteration

【讨论】:

  • 数据是对的,除了table_CORE除了ID还有其他字段;虽然我很确定即使在这种情况下你的代码也能正常工作(我稍后会确认,因为我被要求在明天结束之前赶出数据库的原型(它应该是一个两个-月项目...)
  • @CallumP.Robertson 无论从任一表中/选择了多少其他字段,它都应该工作。祝你的原型好运!
  • 我们去 - 设法用上面代码的一个小变种来修复它!感谢捆绑! Ps - 原型非常糟糕:他们认为这并不像他们想象的那么紧急......现在我从假期回来了,但它又很紧急!
  • @CallumP.Robertson 很高兴听到这个消息!玩得开心!
【解决方案3】:
select * 
from 
(
SELECT table_DATES.[date-ID], * 
     , row_number() over (partition by table_CORE date-ID order by iteration desc) as rn
FROM table_CORE 
LEFT JOIN table_DATES 
       ON [table_CORE].[core-ID] =  table_DATES.[date-ID]
WHERE table_CORE.[core-ID] Like '*'
)  tt
where tt.rn = 1
ORDER BY [core-ID]

【讨论】:

    猜你喜欢
    • 2011-01-07
    • 2020-10-21
    • 2017-03-19
    • 1970-01-01
    • 2021-10-31
    • 2021-02-19
    • 2016-08-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多