如何在 SAME table 上分组,按日期排序并限制返回的行数?
How can I group on the SAME table, order by date and limit the number of rows returned?
我想要 return 按 ID_F 分组、数量限制在 ID_F 内并按日期排序在 ID_F
内的集合
这是我的数据库设置:
CREATE TABLE [dbo].[U](
[ID] [uniqueidentifier] NOT NULL,
[Name] [nvarchar](max) NULL,
CONSTRAINT [PK_U] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[F](
[ID] [uniqueidentifier] NOT NULL,
[Name] [nvarchar](max) NOT NULL,
CONSTRAINT [PK_F] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
CREATE TABLE [dbo].[E](
[ID] [uniqueidentifier] NOT NULL,
[Name] [nvarchar](max) NOT NULL,
CONSTRAINT [PK_E] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
CREATE TABLE [dbo].[U_F_E](
[ID] [uniqueidentifier] NOT NULL,
[ID_U] [uniqueidentifier] NOT NULL,
[ID_F] [uniqueidentifier] NOT NULL,
[ID_E] [uniqueidentifier] NOT NULL,
[LastUsed][DateTime] NOT NULL,
CONSTRAINT [PK_U_F_E] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
declare @ID uniqueidentifier
declare @N nvarchar(50)
set @ID = '53159BEC-88C7-48C3-B2D1-63926ED28A64'
set @N = 'Bob'
insert into [U]
Values(
@ID,
@N
)
set @ID = '3DF035A6-C456-4AB4-8BBB-E8FF86A2A033'
set @N = 'Tom'
insert into [U]
Values(
@ID,
@N
)
set @ID = 'F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A'
set @N = 'F1'
insert into [F]
Values(
@ID,
@N
)
set @ID = '220AD0BC-3F20-4F1C-A9B8-81AC08EA679A'
set @N = 'f2'
insert into [F]
Values(
@ID,
@N
)
set @ID = '3708E1E8-6E7E-4E8F-B415-3F09CF22CB54'
set @N = 'f3'
insert into [F]
Values(
@ID,
@N
)
set @ID = 'EA219DA4-6C13-42AA-A1B6-DE786724A554'
set @N = 'e1'
insert into [E]
Values(
@ID,
@N
)
set @ID = '6158853D-E91A-4AA4-AC0F-5D26F766C677'
set @N = 'e2'
insert into [E]
Values(
@ID,
@N
)
set @ID = 'F697F78A-6990-443E-9D4B-D9BCF046DAF5'
set @N = 'e3'
insert into [E]
Values(
@ID,
@N
)
set @ID = 'A7DB1FA5-28D6-4F5A-8BA0-628EA2A630A8'
set @N = 'e4'
insert into [E]
Values(
@ID,
@N
)
set @ID = '8ABEE9FA-B255-4409-A2DD-30CFF62EEE3C'
set @N = 'e5'
insert into [E]
Values(
@ID,
@N
)
set @ID = 'DA644D24-AFA5-467E-A76C-A5E94DA4FA62'
set @N = 'e6'
insert into [E]
Values(
@ID,
@N
)
insert into [U_F_E]
Values(
NEWID(),
'53159BEC-88C7-48C3-B2D1-63926ED28A64', -- bob
'F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A', -- f1
'EA219DA4-6C13-42AA-A1B6-DE786724A554', -- e1
GetDate()
)
WAITFOR DELAY '00:00:01';
insert into [U_F_E]
Values(
NEWID(),
'53159BEC-88C7-48C3-B2D1-63926ED28A64', -- bob
'3708E1E8-6E7E-4E8F-B415-3F09CF22CB54', -- f3
'EA219DA4-6C13-42AA-A1B6-DE786724A554', -- e1
GetDate()
)
WAITFOR DELAY '00:00:01';
insert into [U_F_E]
Values(
NEWID(),
'3DF035A6-C456-4AB4-8BBB-E8FF86A2A033', -- tom
'220AD0BC-3F20-4F1C-A9B8-81AC08EA679A', -- f2
'8ABEE9FA-B255-4409-A2DD-30CFF62EEE3C', -- e5
GetDate()
)
WAITFOR DELAY '00:00:01';
insert into [U_F_E]
Values(
NEWID(),
'53159BEC-88C7-48C3-B2D1-63926ED28A64', -- bob
'220AD0BC-3F20-4F1C-A9B8-81AC08EA679A', -- f2
'8ABEE9FA-B255-4409-A2DD-30CFF62EEE3C', -- e5
GetDate()
)
WAITFOR DELAY '00:00:01';
insert into [U_F_E]
Values(
NEWID(),
'53159BEC-88C7-48C3-B2D1-63926ED28A64', -- bob
'220AD0BC-3F20-4F1C-A9B8-81AC08EA679A', -- f2
'F697F78A-6990-443E-9D4B-D9BCF046DAF5', -- e3
GetDate()
)
WAITFOR DELAY '00:00:01';
insert into [U_F_E]
Values(
NEWID(),
'53159BEC-88C7-48C3-B2D1-63926ED28A64', -- bob
'220AD0BC-3F20-4F1C-A9B8-81AC08EA679A', -- f2
'6158853D-E91A-4AA4-AC0F-5D26F766C677', -- e2
GetDate()
)
WAITFOR DELAY '00:00:01';
insert into [U_F_E]
Values(
NEWID(),
'3DF035A6-C456-4AB4-8BBB-E8FF86A2A033', -- tom
'220AD0BC-3F20-4F1C-A9B8-81AC08EA679A', -- f2
'EA219DA4-6C13-42AA-A1B6-DE786724A554', -- e1
GetDate()
)
WAITFOR DELAY '00:00:01';
insert into [U_F_E]
Values(
NEWID(),
'53159BEC-88C7-48C3-B2D1-63926ED28A64', -- bob
'220AD0BC-3F20-4F1C-A9B8-81AC08EA679A', -- f2
'A7DB1FA5-28D6-4F5A-8BA0-628EA2A630A8', -- e4
GetDate()
)
尝试 0:
declare @limit int
set @limit = 3
declare @myuser uniqueidentifier
set @myuser = '53159BEC-88C7-48C3-B2D1-63926ED28A64'
select ID_F, e.Name, LastUsed from [U_F_E] as ufe
join E as e on ufe.ID_E = e.ID
where ID_U = @myuser
group by ID_F, e.Name, LastUsed
order by LastUsed desc
这是输出,请注意它是按日期分组和排序的...但它不限制 ID_F 行的数量 returned
ID_F Name LastUsed
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 07:58:54.953
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 07:51:49.560
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e2 2016-04-14 07:51:47.537
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e5 2016-04-14 07:51:45.533
3708E1E8-6E7E-4E8F-B415-3F09CF22CB54 e1 2016-04-14 07:51:43.530
F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A e1 2016-04-14 07:51:42.530
当我尝试使用此限制 returned 的行数时:
declare @limit int
set @limit = 3
declare @myuser uniqueidentifier
set @myuser = '53159BEC-88C7-48C3-B2D1-63926ED28A64'
select TOP(@limit) ID_F, e.Name, LastUsed from [U_F_E] as ufe
join E as e on ufe.ID_E = e.ID
where ID_U = @myuser
group by ID_F, e.Name, LastUsed
order by LastUsed desc
我明白了:
ID_F Name LastUsed
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 07:58:54.953
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 07:51:49.560
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e2 2016-04-14 07:51:47.537
当我真正想要这个时:
ID_F Name LastUsed
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 07:58:54.953
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 07:51:49.560
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e2 2016-04-14 07:51:47.537
3708E1E8-6E7E-4E8F-B415-3F09CF22CB54 e1 2016-04-14 07:51:43.530
F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A e1 2016-04-14 07:51:42.530
你能帮帮我吗?
尝试 1:
select id_f,name,lastused
from (
select ID_F, e.Name, LastUsed
,dense_rank() over(partition by ID_U order by ID_F) as rnk
from [U_F_E] as ufe
join E as e on ufe.ID_E = e.ID
where ID_U = @myuser) t
where rnk <= 3
order by lastused desc
returns,但不考虑限制行 returned:
id_f name lastused
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 07:58:54.953
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 07:51:49.560
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e2 2016-04-14 07:51:47.537
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e5 2016-04-14 07:51:45.533
3708E1E8-6E7E-4E8F-B415-3F09CF22CB54 e1 2016-04-14 07:51:43.530
F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A e1 2016-04-14 07:51:42.530
我假设“3”应该像这样限制 ID_F 行 return?
id_f name lastused
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 07:58:54.953
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 07:51:49.560
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e2 2016-04-14 07:51:47.537
3708E1E8-6E7E-4E8F-B415-3F09CF22CB54 e1 2016-04-14 07:51:43.530
F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A e1 2016-04-14 07:51:42.530
尝试 2:
SELECT id_f, fe.*
FROM [U_F_E] uf
CROSS APPLY
(
SELECT TOP (@limit) e.Name, LastUsed
FROM [U_F_E] fe
JOIN [E] e
ON e.id = fe.id_e
WHERE id_f = uf.id_f
ORDER BY LastUsed DESC
) fe
WHERE id_u = @myuser
但这还差得远……它 return 的行数太疯狂了。
id_f Name LastUsed
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 07:58:54.953
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e5 2016-04-14 07:55:38.870
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 07:51:49.560
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 07:58:54.953
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e5 2016-04-14 07:55:38.870
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 07:51:49.560
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 07:58:54.953
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e5 2016-04-14 07:55:38.870
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 07:51:49.560
F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A e1 2016-04-14 07:51:42.530
3708E1E8-6E7E-4E8F-B415-3F09CF22CB54 e1 2016-04-14 07:51:43.530
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 07:58:54.953
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e5 2016-04-14 07:55:38.870
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 07:51:49.560
尝试 3:
select id_f,name,lastused
from (
select ID_F, e.Name, LastUsed
,row_number() over(partition by ID_F order by lastused desc) as rnk
from [U_F_E] as ufe
join E as e on ufe.ID_E = e.ID
where ID_U = @myuser) t
where rnk <= @limit
order by lastused desc
给出这个:
id_f name lastused
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 07:58:54.953
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 07:51:49.560
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e2 2016-04-14 07:51:47.537
3708E1E8-6E7E-4E8F-B415-3F09CF22CB54 e1 2016-04-14 07:51:43.530
F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A e1 2016-04-14 07:51:42.530
但是当我向 table 添加另一行时,请注意 370 未分组
id_f name lastused
3708E1E8-6E7E-4E8F-B415-3F09CF22CB54 e5 2016-04-14 08:53:21.233
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 08:50:03.187
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e5 2016-04-14 08:45:00.897
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 08:43:42.253
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e2 2016-04-14 07:51:47.537
3708E1E8-6E7E-4E8F-B415-3F09CF22CB54 e1 2016-04-14 07:51:43.530
F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A e1 2016-04-14 07:51:42.530
尝试 4:
select id_f,name,lastused
from (
select ID_F, e.Name, LastUsed
,row_number() over(partition by ID_F order by lastused desc) as rnk
from [U_F_E] as ufe
join E as e on ufe.ID_E = e.ID
where ID_U = @myuser) t
where rnk <= @limit
order by ID_F, lastused desc
产生:(当限制设置为 3 时)
id_f name lastused
3708E1E8-6E7E-4E8F-B415-3F09CF22CB54 e5 2016-04-14 08:53:21.233
3708E1E8-6E7E-4E8F-B415-3F09CF22CB54 e1 2016-04-14 07:51:43.530
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 08:50:03.187
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e5 2016-04-14 08:45:00.897
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 08:43:42.253
F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 09:00:27.780
F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A e1 2016-04-14 07:51:42.530
谢谢你!
您可以使用dense_rank
功能并检查。
select id_f,name,lastused
from (
select ID_F, e.Name, LastUsed
,dense_rank() over(partition by ID_U order by ID_F) as rnk
from [U_F_E] as ufe
join E as e on ufe.ID_E = e.ID
where ID_U = @myuser) t
where rnk <= 3
order by lastused desc
经过chat的一番讨论,发现主要是显示问题:
select id_f,name,lastused
from
(
select ID_F, e.Name, LastUsed
,row_number() -- ranking
over(partition by ID_F -- for each ID_F
order by lastused desc) as rnk -- based on descending dates
from [U_F_E] as ufe
join E as e on ufe.ID_E = e.ID
where ID_U = @myuser
) t
where rnk <= @limit
order by ID_F, lastused desc -- sort the correct way :-)
我想要 return 按 ID_F 分组、数量限制在 ID_F 内并按日期排序在 ID_F
内的集合这是我的数据库设置:
CREATE TABLE [dbo].[U](
[ID] [uniqueidentifier] NOT NULL,
[Name] [nvarchar](max) NULL,
CONSTRAINT [PK_U] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[F](
[ID] [uniqueidentifier] NOT NULL,
[Name] [nvarchar](max) NOT NULL,
CONSTRAINT [PK_F] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
CREATE TABLE [dbo].[E](
[ID] [uniqueidentifier] NOT NULL,
[Name] [nvarchar](max) NOT NULL,
CONSTRAINT [PK_E] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
CREATE TABLE [dbo].[U_F_E](
[ID] [uniqueidentifier] NOT NULL,
[ID_U] [uniqueidentifier] NOT NULL,
[ID_F] [uniqueidentifier] NOT NULL,
[ID_E] [uniqueidentifier] NOT NULL,
[LastUsed][DateTime] NOT NULL,
CONSTRAINT [PK_U_F_E] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
declare @ID uniqueidentifier
declare @N nvarchar(50)
set @ID = '53159BEC-88C7-48C3-B2D1-63926ED28A64'
set @N = 'Bob'
insert into [U]
Values(
@ID,
@N
)
set @ID = '3DF035A6-C456-4AB4-8BBB-E8FF86A2A033'
set @N = 'Tom'
insert into [U]
Values(
@ID,
@N
)
set @ID = 'F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A'
set @N = 'F1'
insert into [F]
Values(
@ID,
@N
)
set @ID = '220AD0BC-3F20-4F1C-A9B8-81AC08EA679A'
set @N = 'f2'
insert into [F]
Values(
@ID,
@N
)
set @ID = '3708E1E8-6E7E-4E8F-B415-3F09CF22CB54'
set @N = 'f3'
insert into [F]
Values(
@ID,
@N
)
set @ID = 'EA219DA4-6C13-42AA-A1B6-DE786724A554'
set @N = 'e1'
insert into [E]
Values(
@ID,
@N
)
set @ID = '6158853D-E91A-4AA4-AC0F-5D26F766C677'
set @N = 'e2'
insert into [E]
Values(
@ID,
@N
)
set @ID = 'F697F78A-6990-443E-9D4B-D9BCF046DAF5'
set @N = 'e3'
insert into [E]
Values(
@ID,
@N
)
set @ID = 'A7DB1FA5-28D6-4F5A-8BA0-628EA2A630A8'
set @N = 'e4'
insert into [E]
Values(
@ID,
@N
)
set @ID = '8ABEE9FA-B255-4409-A2DD-30CFF62EEE3C'
set @N = 'e5'
insert into [E]
Values(
@ID,
@N
)
set @ID = 'DA644D24-AFA5-467E-A76C-A5E94DA4FA62'
set @N = 'e6'
insert into [E]
Values(
@ID,
@N
)
insert into [U_F_E]
Values(
NEWID(),
'53159BEC-88C7-48C3-B2D1-63926ED28A64', -- bob
'F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A', -- f1
'EA219DA4-6C13-42AA-A1B6-DE786724A554', -- e1
GetDate()
)
WAITFOR DELAY '00:00:01';
insert into [U_F_E]
Values(
NEWID(),
'53159BEC-88C7-48C3-B2D1-63926ED28A64', -- bob
'3708E1E8-6E7E-4E8F-B415-3F09CF22CB54', -- f3
'EA219DA4-6C13-42AA-A1B6-DE786724A554', -- e1
GetDate()
)
WAITFOR DELAY '00:00:01';
insert into [U_F_E]
Values(
NEWID(),
'3DF035A6-C456-4AB4-8BBB-E8FF86A2A033', -- tom
'220AD0BC-3F20-4F1C-A9B8-81AC08EA679A', -- f2
'8ABEE9FA-B255-4409-A2DD-30CFF62EEE3C', -- e5
GetDate()
)
WAITFOR DELAY '00:00:01';
insert into [U_F_E]
Values(
NEWID(),
'53159BEC-88C7-48C3-B2D1-63926ED28A64', -- bob
'220AD0BC-3F20-4F1C-A9B8-81AC08EA679A', -- f2
'8ABEE9FA-B255-4409-A2DD-30CFF62EEE3C', -- e5
GetDate()
)
WAITFOR DELAY '00:00:01';
insert into [U_F_E]
Values(
NEWID(),
'53159BEC-88C7-48C3-B2D1-63926ED28A64', -- bob
'220AD0BC-3F20-4F1C-A9B8-81AC08EA679A', -- f2
'F697F78A-6990-443E-9D4B-D9BCF046DAF5', -- e3
GetDate()
)
WAITFOR DELAY '00:00:01';
insert into [U_F_E]
Values(
NEWID(),
'53159BEC-88C7-48C3-B2D1-63926ED28A64', -- bob
'220AD0BC-3F20-4F1C-A9B8-81AC08EA679A', -- f2
'6158853D-E91A-4AA4-AC0F-5D26F766C677', -- e2
GetDate()
)
WAITFOR DELAY '00:00:01';
insert into [U_F_E]
Values(
NEWID(),
'3DF035A6-C456-4AB4-8BBB-E8FF86A2A033', -- tom
'220AD0BC-3F20-4F1C-A9B8-81AC08EA679A', -- f2
'EA219DA4-6C13-42AA-A1B6-DE786724A554', -- e1
GetDate()
)
WAITFOR DELAY '00:00:01';
insert into [U_F_E]
Values(
NEWID(),
'53159BEC-88C7-48C3-B2D1-63926ED28A64', -- bob
'220AD0BC-3F20-4F1C-A9B8-81AC08EA679A', -- f2
'A7DB1FA5-28D6-4F5A-8BA0-628EA2A630A8', -- e4
GetDate()
)
尝试 0:
declare @limit int
set @limit = 3
declare @myuser uniqueidentifier
set @myuser = '53159BEC-88C7-48C3-B2D1-63926ED28A64'
select ID_F, e.Name, LastUsed from [U_F_E] as ufe
join E as e on ufe.ID_E = e.ID
where ID_U = @myuser
group by ID_F, e.Name, LastUsed
order by LastUsed desc
这是输出,请注意它是按日期分组和排序的...但它不限制 ID_F 行的数量 returned
ID_F Name LastUsed
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 07:58:54.953
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 07:51:49.560
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e2 2016-04-14 07:51:47.537
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e5 2016-04-14 07:51:45.533
3708E1E8-6E7E-4E8F-B415-3F09CF22CB54 e1 2016-04-14 07:51:43.530
F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A e1 2016-04-14 07:51:42.530
当我尝试使用此限制 returned 的行数时:
declare @limit int
set @limit = 3
declare @myuser uniqueidentifier
set @myuser = '53159BEC-88C7-48C3-B2D1-63926ED28A64'
select TOP(@limit) ID_F, e.Name, LastUsed from [U_F_E] as ufe
join E as e on ufe.ID_E = e.ID
where ID_U = @myuser
group by ID_F, e.Name, LastUsed
order by LastUsed desc
我明白了:
ID_F Name LastUsed
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 07:58:54.953
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 07:51:49.560
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e2 2016-04-14 07:51:47.537
当我真正想要这个时:
ID_F Name LastUsed
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 07:58:54.953
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 07:51:49.560
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e2 2016-04-14 07:51:47.537
3708E1E8-6E7E-4E8F-B415-3F09CF22CB54 e1 2016-04-14 07:51:43.530
F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A e1 2016-04-14 07:51:42.530
你能帮帮我吗?
尝试 1:
select id_f,name,lastused
from (
select ID_F, e.Name, LastUsed
,dense_rank() over(partition by ID_U order by ID_F) as rnk
from [U_F_E] as ufe
join E as e on ufe.ID_E = e.ID
where ID_U = @myuser) t
where rnk <= 3
order by lastused desc
returns,但不考虑限制行 returned:
id_f name lastused
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 07:58:54.953
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 07:51:49.560
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e2 2016-04-14 07:51:47.537
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e5 2016-04-14 07:51:45.533
3708E1E8-6E7E-4E8F-B415-3F09CF22CB54 e1 2016-04-14 07:51:43.530
F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A e1 2016-04-14 07:51:42.530
我假设“3”应该像这样限制 ID_F 行 return?
id_f name lastused
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 07:58:54.953
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 07:51:49.560
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e2 2016-04-14 07:51:47.537
3708E1E8-6E7E-4E8F-B415-3F09CF22CB54 e1 2016-04-14 07:51:43.530
F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A e1 2016-04-14 07:51:42.530
尝试 2:
SELECT id_f, fe.*
FROM [U_F_E] uf
CROSS APPLY
(
SELECT TOP (@limit) e.Name, LastUsed
FROM [U_F_E] fe
JOIN [E] e
ON e.id = fe.id_e
WHERE id_f = uf.id_f
ORDER BY LastUsed DESC
) fe
WHERE id_u = @myuser
但这还差得远……它 return 的行数太疯狂了。
id_f Name LastUsed
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 07:58:54.953
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e5 2016-04-14 07:55:38.870
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 07:51:49.560
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 07:58:54.953
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e5 2016-04-14 07:55:38.870
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 07:51:49.560
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 07:58:54.953
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e5 2016-04-14 07:55:38.870
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 07:51:49.560
F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A e1 2016-04-14 07:51:42.530
3708E1E8-6E7E-4E8F-B415-3F09CF22CB54 e1 2016-04-14 07:51:43.530
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 07:58:54.953
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e5 2016-04-14 07:55:38.870
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 07:51:49.560
尝试 3:
select id_f,name,lastused
from (
select ID_F, e.Name, LastUsed
,row_number() over(partition by ID_F order by lastused desc) as rnk
from [U_F_E] as ufe
join E as e on ufe.ID_E = e.ID
where ID_U = @myuser) t
where rnk <= @limit
order by lastused desc
给出这个:
id_f name lastused
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 07:58:54.953
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 07:51:49.560
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e2 2016-04-14 07:51:47.537
3708E1E8-6E7E-4E8F-B415-3F09CF22CB54 e1 2016-04-14 07:51:43.530
F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A e1 2016-04-14 07:51:42.530
但是当我向 table 添加另一行时,请注意 370 未分组
id_f name lastused
3708E1E8-6E7E-4E8F-B415-3F09CF22CB54 e5 2016-04-14 08:53:21.233
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 08:50:03.187
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e5 2016-04-14 08:45:00.897
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 08:43:42.253
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e2 2016-04-14 07:51:47.537
3708E1E8-6E7E-4E8F-B415-3F09CF22CB54 e1 2016-04-14 07:51:43.530
F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A e1 2016-04-14 07:51:42.530
尝试 4:
select id_f,name,lastused
from (
select ID_F, e.Name, LastUsed
,row_number() over(partition by ID_F order by lastused desc) as rnk
from [U_F_E] as ufe
join E as e on ufe.ID_E = e.ID
where ID_U = @myuser) t
where rnk <= @limit
order by ID_F, lastused desc
产生:(当限制设置为 3 时)
id_f name lastused
3708E1E8-6E7E-4E8F-B415-3F09CF22CB54 e5 2016-04-14 08:53:21.233
3708E1E8-6E7E-4E8F-B415-3F09CF22CB54 e1 2016-04-14 07:51:43.530
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 08:50:03.187
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e5 2016-04-14 08:45:00.897
220AD0BC-3F20-4F1C-A9B8-81AC08EA679A e3 2016-04-14 08:43:42.253
F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A e4 2016-04-14 09:00:27.780
F20AD0BC-3F20-4F1C-A9B8-81AC08EA679A e1 2016-04-14 07:51:42.530
谢谢你!
您可以使用dense_rank
功能并检查。
select id_f,name,lastused
from (
select ID_F, e.Name, LastUsed
,dense_rank() over(partition by ID_U order by ID_F) as rnk
from [U_F_E] as ufe
join E as e on ufe.ID_E = e.ID
where ID_U = @myuser) t
where rnk <= 3
order by lastused desc
经过chat的一番讨论,发现主要是显示问题:
select id_f,name,lastused
from
(
select ID_F, e.Name, LastUsed
,row_number() -- ranking
over(partition by ID_F -- for each ID_F
order by lastused desc) as rnk -- based on descending dates
from [U_F_E] as ufe
join E as e on ufe.ID_E = e.ID
where ID_U = @myuser
) t
where rnk <= @limit
order by ID_F, lastused desc -- sort the correct way :-)