如何选择与复合主键表不同

时间:2017-03-13 20:43:05

标签: sql sql-server

我想了解如何使用两个主键从SQL表中过滤掉select

╔═══════════════════╦════════════════════╦════════════╗
║ First Primary Key ║ Second Primary Key ║ Data       ║
╠═══════════════════╬════════════════════╬════════════╣
║ 1                 ║ 1                  ║ Bla,bla,bla║
║ 1                 ║ 2                  ║ Bla,bla,bla║
║ 1                 ║ 3                  ║ Bla,bla,bla║
║ 1                 ║ 4                  ║ Bla,bla,bla║
║ 2                 ║ 5                  ║ Bla,bla,bla║
║ 2                 ║ 6                  ║ Bla,bla,bla║
║ 2                 ║ 7                  ║ Bla,bla,bla║
║ 3                 ║ 8                  ║ Bla,bla,bla║
║ 4                 ║ 9                  ║ Bla,bla,bla║
║ 4                 ║ 10                 ║ Bla,bla,bla║
║ 4                 ║ 11                 ║ Bla,bla,bla║
║ 4                 ║ 12                 ║ Bla,bla,bla║
╚═══════════════════╩════════════════════╩════════════╝

我想distinct第一列,只从第二列中取max(Second_Primary_Key)

我想要的结果是

╔═══════════════════╦════════════════════╦════════════╗
║ First_Primary_Key ║ Second_Primary_Key ║ Data       ║
╠═══════════════════╬════════════════════╬════════════╣
║ 1                 ║ 4                  ║ Bla,bla,bla║
║ 2                 ║ 7                  ║ Bla,bla,bla║
║ 3                 ║ 8                  ║ Bla,bla,bla║
║ 4                 ║ 12                 ║ Bla,bla,bla║
╚═══════════════════╩════════════════════╩════════════╝

结构应该是:

select * from foo  
where (distinct First_Primary_Key) and max(Second_Primary_Key)

3 个答案:

答案 0 :(得分:4)

select First_PK, max(Second_PK) from foo group by First_PK

为了获得数据,我更喜欢使用窗口函数:

; with temp as (
 select row_number() over (partition by First_PK order by Second_PK desc)
   as row_num, First_PK, Second_PK, data
 from test)
 select * from temp
 where row_num = 1

答案 1 :(得分:2)

您可以使用

执行group by然后join
select t1.first_primary_key, xxx.second_primary_key, t1.data
from tbl1 t1 join (
select first_primary_key, max(second_primary_key) as second_primary_key
from tbl1 
group by first_primary_key ) xxx 
on t1.first_primary_key = xxx.first_primary_key
AND t1.second_primary_key = xxx.second_primary_key;

答案 2 :(得分:1)

使用row_number()获得Second_Primary_Key每个First_Primary_Key最高select sub.First_Primary_Key, sub.Second_Primary_Key, sub.[Data] from ( select * , rn = row_number() over ( partition by First_Primary_Key order by Second_Primary_Key desc ) from t ) as sub where sub.rn = 1 (每组排名前1位),使用row_number()

cross

select distinct t.First_Primary_Key , x.Second_Primary_Key , x.[Data] from t cross apply ( select top 1 * from t as i where i.First_Primary_Key = t.First_Primary_Key order by i.Second_Primary_Key desc ) as x; apply 版本:

select top 1 with ties
    *
  from t
  order by 
    row_number() over (
      partition by First_Primary_Key
      order by Second_Primary_Key desc
      )

top with ties 使用row_number()版本:

inner join

rank()版本与使用row_number()而不是inner join具有相同的问题,因为如果First_Primary_Key具有多个具有相同的行,则可以获得相同First_Primary_Key的多个结果max Second_Primary_Key。

select t.* from t inner join ( select MaxSecond_Primary_Key = max(Second_Primary_Key), First_Primary_Key from t group by First_Primary_Key ) as m on t.First_Primary_Key = m.First_Primary_Key and t.Second_Primary_Key = m.MaxSecond_Primary_Key; 版本:

<?xml version="1.0" encoding="UTF-8"?>
   <Department>
      <dept_id>1</dept_id>
      <name>dep1</name>
      <location>loc1</location>
   </Department>