Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL从一个表中选择多个不同的记录_Sql_Sql Server_Tsql_Sql Server 2008 R2_Greatest N Per Group - Fatal编程技术网

SQL从一个表中选择多个不同的记录

SQL从一个表中选择多个不同的记录,sql,sql-server,tsql,sql-server-2008-r2,greatest-n-per-group,Sql,Sql Server,Tsql,Sql Server 2008 R2,Greatest N Per Group,我有一张如下的桌子 ID |FromId |ToId |Message|DateTime ------------------------------------------ 1 |1 |2 |a |15:00 2 |1 |2 |b |15:01 3 |1 |2 |c |15:02 4 |2 |1 |d |15:03 5 |3 |1

我有一张如下的桌子

ID  |FromId |ToId   |Message|DateTime
------------------------------------------
1   |1      |2      |a      |15:00
2   |1      |2      |b      |15:01
3   |1      |2      |c      |15:02
4   |2      |1      |d      |15:03
5   |3      |1      |e      |15:04
6   |3      |1      |f      |15:05
7   |1      |3      |g      |15:06
我想得到的是同龄人的每一条信息

例如:用户1和用户2有4条消息(ID:1,2,3,4),用户1和用户3有3条消息(ID:5,6,7)

我只想从用户那里获取最新的消息记录,我需要一个SQL查询,它将给出如下结果:

*sql code here ? -- I need this.
结果(对于:其中UserID=1):

有什么想法吗?我试过使用DISTINCE等,但不知怎的都没用。请帮忙

对不起,伙计们,我想我忘了提到我需要来自同行的最新记录,而不是来自一个用户的最新记录,例如,对于用户1和用户2,我需要来自他们的最新记录,不知道是来自哪个用户还是来自哪个用户。。我需要这两个数据库中的最新记录,在我们的案例中为ID 4,没有其他记录。

create function getlastmessage(
@userid int
)
returns nvarchar(max)
as
select top(1), message from messages 
 where userid=@userid order by messageid desc
在人物表中

select *, getlastmessage(actorid) as lastmessage from people


如果您不想使用函数

select 
*, 
(select top(1), message from messages 
  where messages.userid=people.userid order by messageid desc) as lastmessage 
 from people
会有点乱

在人物表中

select *, getlastmessage(actorid) as lastmessage from people


如果您不想使用函数

select 
*, 
(select top(1), message from messages 
  where messages.userid=people.userid order by messageid desc) as lastmessage 
 from people

这将有点混乱。

您需要进行自引用联接,因此内部查询选择每个组的最大值,外部查询选择匹配的每行的所有数据

select * 
from thetable t1 
join(select max(ID) as id,
            FromID 
     from thetable
     group by FromID)t2 on (t1.id=t2.id);

您需要执行自引用联接,因此内部查询选择每个组的最大值,外部查询选择匹配的每行的所有数据

select * 
from thetable t1 
join(select max(ID) as id,
            FromID 
     from thetable
     group by FromID)t2 on (t1.id=t2.id);
使用此Sql进行以下操作:

Declare @tempTeable Table
(
 Id int,
 FromID int,
 ToId int,
 SMessage nvarchar(250),
 SDateTime Time 
)

Insert into @tempTeable values(1,1,2,'a','15:00')
Insert into @tempTeable values(2,1,2,'b','15:01')
Insert into @tempTeable values(3,1,2,'c','15:02')
Insert into @tempTeable values(4,2,1,'d','15:03')
Insert into @tempTeable values(5,3,1,'e','15:04')
Insert into @tempTeable values(6,3,1,'f','15:05')
Insert into @tempTeable values(7,1,3,'g','15:06')

select distinct t1.* from @tempTeable as t1
inner join 
  (select UserID,MAX(SDateTime)as SDateTime from
    (
      select FromId as UserId ,MAX(SDateTime)as SDateTime from  @tempTeable group by 
       FromId
       UNION
       select ToId as UserId,MAX(SDateTime)as SDateTime from  @tempTeable group by   
        ToId) as tbl
        group by UserId) as tblres 
  on (t1.FromID =tblres.UserId  or t1.toId =tblres.UserId) 
  and t1.SDateTime=tblres.SDateTime 
使用此Sql进行以下操作:

Declare @tempTeable Table
(
 Id int,
 FromID int,
 ToId int,
 SMessage nvarchar(250),
 SDateTime Time 
)

Insert into @tempTeable values(1,1,2,'a','15:00')
Insert into @tempTeable values(2,1,2,'b','15:01')
Insert into @tempTeable values(3,1,2,'c','15:02')
Insert into @tempTeable values(4,2,1,'d','15:03')
Insert into @tempTeable values(5,3,1,'e','15:04')
Insert into @tempTeable values(6,3,1,'f','15:05')
Insert into @tempTeable values(7,1,3,'g','15:06')

select distinct t1.* from @tempTeable as t1
inner join 
  (select UserID,MAX(SDateTime)as SDateTime from
    (
      select FromId as UserId ,MAX(SDateTime)as SDateTime from  @tempTeable group by 
       FromId
       UNION
       select ToId as UserId,MAX(SDateTime)as SDateTime from  @tempTeable group by   
        ToId) as tbl
        group by UserId) as tblres 
  on (t1.FromID =tblres.UserId  or t1.toId =tblres.UserId) 
  and t1.SDateTime=tblres.SDateTime 

如果是Sql Server 2005+,则可以使用对记录进行分组、排序和编号,然后仅检索组中第一个记录:

; with cte as
(
  select *,
      -- Group by user not being searched for
         row_number() over (partition by case when FromID = @UserID
                                              then ToID
                                              else FromID
                                          end
      -- Last date will be numbered as 1
                            order by [DateTime] desc
                           ) rn
    from Table1
-- Filter only messages sent from or received by certain user
   where (FromID = @UserID or ToID = @UserID)
)
select *
  from cte
-- Get last dates only
 where rn = 1

如果是Sql Server 2005+,则可以使用对记录进行分组、排序和编号,然后仅检索组中第一个记录:

; with cte as
(
  select *,
      -- Group by user not being searched for
         row_number() over (partition by case when FromID = @UserID
                                              then ToID
                                              else FromID
                                          end
      -- Last date will be numbered as 1
                            order by [DateTime] desc
                           ) rn
    from Table1
-- Filter only messages sent from or received by certain user
   where (FromID = @UserID or ToID = @UserID)
)
select *
  from cte
-- Get last dates only
 where rn = 1
试试这个:

;WITH CTE As(
select id,fromID,ToID,Message,DateTime,0 as sel from Msgs where id=1
union all
select m.id,m.fromID,m.ToID,m.Message,m.DateTime,
CASE WHEN (m.FromId =c.FromId or m.FromId =c.ToId) then 0 else 1 end as sel 
from CTE c inner join Msgs m 
--on (c.FromId = m.FromId and c.ToId = m.ToId) or (c.FromId = m.ToId and c.ToId = m.FromId)
on m.id=c.Id+1
)

select * from CTE where ID in (select ID-1 from CTE where sel=1)
union
select * from CTE where ID = (select max(id) from CTE)
试试这个:

;WITH CTE As(
select id,fromID,ToID,Message,DateTime,0 as sel from Msgs where id=1
union all
select m.id,m.fromID,m.ToID,m.Message,m.DateTime,
CASE WHEN (m.FromId =c.FromId or m.FromId =c.ToId) then 0 else 1 end as sel 
from CTE c inner join Msgs m 
--on (c.FromId = m.FromId and c.ToId = m.ToId) or (c.FromId = m.ToId and c.ToId = m.FromId)
on m.id=c.Id+1
)

select * from CTE where ID in (select ID-1 from CTE where sel=1)
union
select * from CTE where ID = (select max(id) from CTE)


您使用的是哪个版本的Sql Server?我使用的是MSSQL 2008 R2您使用的是哪个版本的Sql Server?我使用的是MSSQL 2008 R2使用的函数将起作用,但是您最终会对表中的每个distinct-fromid执行一个额外的查询…您是希望执行两个查询并让服务器对两个表之间的索引执行联接,还是让N个查询运行,其中N是数据库中的distinct-id数。。随着时间的推移,您将遇到缩放问题。@Stephen第二个查询中的select(max)已经执行了N次。因此,从技术上讲,您在不同的查询上执行相同的工作,并除此之外执行联接。区别在于,我只收集了一次数据,然后执行联接。。使用函数要求您对每一行执行一个全新的查询…@Stephen问题是,当您使用group by收集数据时,执行过程采用相同的步骤。使用函数将起作用,但是您最终会对表中的每个distinct-fromid执行一个额外的查询…您是希望执行两个查询并让服务器对两个表之间的索引执行联接,还是让N个查询运行,其中N是数据库中的distinct-id数。。随着时间的推移,您将遇到缩放问题。@Stephen第二个查询中的select(max)已经执行了N次。因此,从技术上讲,您在不同的查询上执行相同的工作,并除此之外执行联接。区别在于,我只收集了一次数据,然后执行联接。。使用函数需要对每一行执行一个全新的查询…@Stephen问题是,当您使用group by收集数据时,执行过程采用相同的步骤。这是可以的,但它只从用户处获取最新消息我需要从Peer处获取最新消息这是可以的,但它只从用户处获取最新消息我需要从Peer处获取最新消息我想他需要的是所有用户的结果集,而不是一个特定用户的结果集,但不确定。@Nikola感谢您的回答。我认为这将是最好的解决方案。@adnanturken My bad,您的数据样本没有显示任何超出筛选范围的行,因此我认为您需要所有用户。:D实际上我的错误让我来解决这个问题:)我想他需要的是所有用户的结果集,而不是一个特定的用户,但不确定。@Nikola感谢您的回答。我认为这将是最好的解决方案。@adnanturken My bad,您的数据样本没有显示任何超出筛选范围的行,因此我认为您需要所有用户。:D实际上我的错误让我来解决这个问题:)工作正常,但成本比CTE版本高5倍左右。工作正常,但成本比CTE版本高5倍左右。