SQL,加入两个表。 table1中唯一的ID,但在table2中重复。从基于table2的记录字段中选择要包含的记录

时间:2012-08-11 14:09:32

标签: sql ms-access

我正在尝试根据帐户ID加入两个表中的所有字段。帐户ID在表1中是唯一的,但在表2中重复。在表2中,我只想为每个ID提取一个记录。

表1:

ID...Field1....Field2

1......aa.........bb  
2......cc.........dd  
3......ee.........ff  
4......gg.........hh  

表2:

ID...Field3....Field4......Field5

1.....123........123...........123  
1.....345........546...........453   
2.....123........123...........123  
3.....123........123...........123  
4.....123........123...........722   
4.....123........123...........333  
4.....123........123...........123 

我需要根据三个字段中的值来选择从表2中提取的ID。逻辑就像这样。在重复项中,选择field3中具有最高值的ID记录,如果它们全部相同,则选择field4中具有最高值的ID记录,如果它们仍然相同,则选择具有最高值的记录。字段5。

所以最终结果如下:

ID....Field1.....Field2.....Field3.....5ield4.....Field5   
1........aa..........bb............345.......546.........452   
2........cc..........dd............123.......123.........123   
3........ee..........ff............123.......123.........123   
4........gg..........hh............123.......123.........722  

非常感谢你!这个已经让我困扰了一段时间

4 个答案:

答案 0 :(得分:2)

jdevelop有一个好主意,但它没有考虑到field3需要优先于field4等的事实。

我不相信访问中存在rownumber,这会简化很多事情。我很长时间没有使用过访问权限,所以你可能需要修改下面的内容,但它应该会让你几乎一路走来。如果这是一次性的努力,那么您可以排序然后添加自动编号字段。如果没有:

SELECT a.id, d.field3, d.field4, max(d.field5) as m_field5
FROM (((Table1 a
INNER JOIN (
    select id, max(field3) as m3
    from table2
    group by id
    ) b on a.id = b.id                        )
INNER JOIN (
    select id, field3, max(field4) as m4
    from table2
    group by id, field3
    ) c
    on b.id = c.id
    and b.m3 = c.field3                       )
INNER JOIN table2 d
    on c.id = d.id
    and c.field3 = d.field3
    and c.m4 = d.field4                       )
group by a.id, d.field3, d.field4

注:根据dbenham的建议编辑 注2:编辑为连接添加括号,因为访问在进行多个连接时需要额外的括号

如果一次性努力或者你可以获得一个rownumber,你可能会做类似的事情:

select id, field3, field4, field5, rownumber
into #temp_ordered
from table2
order by id, field3, field4, field5

select a.*
from #temp_ordered a
inner join (
    select id, min(rownumber) min_rownumber
    from #temp_ordered 
    group by id
    ) b on a.id = b.id and a.rownumber = b.min_rownumber

最佳, 大卫

答案 1 :(得分:1)

我假设您正在使用MSSQL Server。您需要使用CROSS APPLY才能解决问题。

SELECT a.*, x.*
FROM   tb1 a 
CROSS APPLY 
(
    SELECT   TOP 1 *
    FROM     tb2 b
    WHERE    a.id = b.id
    ORDER BY f3 desc, f4 desc, f5 desc
) x

SQLFiddle Demo

答案 2 :(得分:1)

(这个答案是在OP确定Access作为目标数据库之前开发的)

以下ANSI语法非常有效,可用于各种数据库,包括:

  • Oracle 11及更高版本(如果CTE移动到内联视图,则可以追溯到8i)
  • SqlServer 2005及更高版本
  • PostgreSQL 8.4及更高版本

with t2 as (
  select id,
         field3,
         field4,
         field5,
         row_number()
           over( partition by id
                 order by field3 desc, field4 desc, field5 desc
               ) as pref
    from table2
)
select t1.id,
       t1.field1,
       t1.field2,
       t2.field3,
       t2.field4,
       t2.field5
  from table1 t1
  join t2
    on t1.id=t2.id
   and t2.pref=1

Oracle使用KEEP LAST的方法更加高效,无需任何子查询或CTE。我相信SqlServer 2012可能已经引入了不同语法的类似功能,但我不熟悉它。

select id,
       field1,
       field2,
       max(field3) keep (dense_rank last order by field3, field4, field5)
       max(field4) keep (dense_rank last order by field3, field4, field5)
       max(field5) keep (dense_rank last order by field3, field4, field5)
  from table1
  join table2 using(id)
 group by id

以下是两个Oracle查询的SQL Fiddle

答案 3 :(得分:0)

 SELECT T1.ID,F1,F2,MAX(F3) F3,MAX(F4) F4,MAX(F5) F5
 FROM TBL1 T1,TBL2 T2
 WHERE T1.ID=T2.ID
 GROUP BY T1.ID,F1,F2
 ORDER BY T1.ID;
                  (OR)
 SELECT T1.ID,F1,F2,F3,F4,F5
 FROM TBL1 T1,(SELECT ID,MAX(F3) F3,MAX(F4) F4,MAX(F5) F5 FROM TBL2 GROUP BY ID) T2
 WHERE T1.ID=T2.ID
 ORDER BY T1.ID;

我希望这两种解决方案都能解决。