Sql 数据库设计是否规范化
我有下列表格Sql 数据库设计是否规范化,sql,sql-server,tsql,database-design,Sql,Sql Server,Tsql,Database Design,我有下列表格 Groups - Id - Name People - Id - GroupId - EntryDate (DateTime) 现在我想检索所有按组的最新人员entrydate排序的组 //pseudo code select * from groups order by (select top 1 from people order by entrydate desc) 是否最好在组中添加LatestEntryDate字段,并在添加人员时更新该字段?因为这将是一个常见的查
Groups
- Id
- Name
People
- Id
- GroupId
- EntryDate (DateTime)
现在我想检索所有按组的最新人员entrydate排序的组
//pseudo code
select * from groups order by (select top 1 from people order by entrydate desc)
是否最好在组中添加LatestEntryDate字段,并在添加人员时更新该字段?因为这将是一个常见的查询
SELECT g.Id, g.Name, MAX(p.EntryDate) AS LatestPeopleEntryDate
FROM Groups g
INNER JOIN People p
ON p.GroupId = g.Id
GROUP BY g.Id, g.Name
ORDER BY MAX(p.EntryDate)
不,我不会将LatestEntryDate
字段添加到Groups
表中。这很容易计算
正如@danihp指出的,您可能需要在此处使用左连接。上面的查询将要求People
表中存在一个值。您选择使用什么取决于您的具体要求
SELECT g.Id, g.Name, MAX(p.EntryDate) AS LatestPeopleEntryDate
FROM Groups g
LEFT JOIN People p
ON p.GroupId = g.Id
GROUP BY g.Id, g.Name
ORDER BY MAX(p.EntryDate)
更新
要回答您关于在Linq中执行此操作的问题,我认为应该是这样的:
var result = groups.Select(g =>
new {
g.Id,
g.Name,
LatestPeopleEntryDate = g.People.Max(p => p.EntryDate)
});
下面是一个带有非常小样本数据的测试示例,它显示了三种方法 要获取最佳查询计划,请执行以下操作: 按(GroupID、EntryDate)为人员设置非唯一索引 A.使用原始伪代码(按顺序执行,但不显示日期)或 B.使用前1个子查询获取并显示日期 A和B的查询计划相同 使用People表的左连接和max()将导致扫描(最多在GroupID中)获得最大值,而不是探测索引中的单个行
set nocount on
if object_id('Groups') is not null drop table Groups
if object_id('People') is not null drop table People
go
-- set up tables
create table Groups
(
ID int primary key,
Name varchar(20)
)
create table People
(
ID int,
GroupID int,
EntryDate datetime
)
-- make an index that is ordered by Group, EntryDate
create index IE_GroupDate on People(GroupID, EntryDate)
-- Sample data
insert into Groups (ID, Name)
values
(1, 'Group1'),
(2, 'Group2'),
(3, 'GroupC')
insert into People (ID, GroupID, EntryDate)
values
(1, 1, '2012-01-01'),
(2, 1, '2012-02-01'),
(1, 3, '2007-12-31')
-- Queries
-- Equivalent to the original poster's intent. Note that it doesn't actually
-- show the entry date
select *
from Groups G
order by (
select top 1 EntryDate
from People P
where P.GroupID = G.ID order by EntryDate desc)
-- Same query (by query plan) but includes the EntryDate in the result set
select
G.ID,
G.Name,
LatestEntryDate = Latest.EntryDate
from Groups G
outer apply (
select top 1 EntryDate
from People P
where P.GroupID = G.ID
order by EntryDate desc
) Latest
order by LatestEntryDate
-- Query using left join. This causes a scan of the left join table to
-- compute the max. (The optimizer isn't smart enough to turn this into
-- a TOP 1)
select
G.ID,
G.Name,
LatestEntryDate = max(P.EntryDate)
from Groups G
left join People P on P.GroupID = G.ID
group by G.ID, G.Name
order by max(P.EntryDate)
Requestions是‘所有组’:“现在我想检索所有按组排序的组,其中包含最新的人员entrydate。”现在是正确的+1我认为应该是‘order by LatestPeopleEntryDate desc’对吗?因为你的问题是“Sorded by group”,所以我按组名对查询进行排序。如果要按日期排序,可以使用
orderbymax(p.EntryDate)
。