复杂的SQL查询 - 合并或替换组

时间:2009-03-26 02:50:10

标签: sql sql-server

我正在建立一个学校网站并且遇到了这个问题。

SQL数据库的结构如下(我没有权限修改他们的数据库)

**GroupRecords**
Id (int, primary key)
Name (nvarchar)
SchoolYear (datetime)
RecordDate (datetime)
IsUpdate (bit)

**People**
Id (int, primary key)
GroupRecordsId (int, foreign key to GroupRecords.Id)
Name (nvarchar)
Bio (nvarchar)
Location (nvarchar)

实际纸质表格看起来像这样,全年都会更新 假设在同一表单(GroupRecords)

中没有重复的参与者名称(People.Name)
-------------------------
Name: District A
SchoolYear: 2000
RecordDate: 12/30/1999
IsUpdate: no

Participants
Name Location
AA   11
BB   22
CC   33
DD   44
-------------------------
-------------------------
Name: District A
SchoolYear: 2000
RecordDate: 1/2/2000
IsUpdate: no

Participants
Name Location
QQ   33
DD   22
EE   99
FF   66
-------------------------
-------------------------
Name: District A
SchoolYear: 2000
RecordDate: 2/1/2000
IsUpdate: yes

Participants
Name Location
XX   00
-------------------------
-------------------------
Name: District A
SchoolYear: 2000
RecordDate: 2/1/2000
IsUpdate: yes

Participants
Name Location
QQ   44
-------------------------

现在这里是棘手的部分 如果IsUpdate为yes,则返回的人员列表应与前一个记录的列表合并 (如果IsUpdate为no:replace,如果IsUpdate为yes:merge)

所以如果查询是GroupRecords.Name ='District A'AND GroupRecords.SchoolYear ='1/1/2000',我应该

QQ   44
DD   22
EE   99
FF   66
XX   00

为此编写存储过程可能会更好吗? 非常感谢你

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[GroupRecords](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](500) NOT NULL,
    [SchoolYear] [datetime] NOT NULL,
    [RecordDate] [datetime] NOT NULL,
    [IsUpdate] [bit] NOT NULL,
 CONSTRAINT [PK_GroupRecords] 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]

GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[People](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [GroupRecordsId] [int] NOT NULL,
    [Name] [nvarchar](500) NOT NULL,
    [Bio] [nvarchar](4000) NOT NULL,
    [Location] [nvarchar](100) NOT NULL,
 CONSTRAINT [PK_People] 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]

GO
ALTER TABLE [dbo].[People]  WITH CHECK ADD  CONSTRAINT [FK_People_GroupRecords] FOREIGN KEY([GroupRecordsId])
REFERENCES [dbo].[GroupRecords] ([Id])
GO
ALTER TABLE [dbo].[People] CHECK CONSTRAINT [FK_People_GroupRecords]

更新 让我澄清IsUpdate如何工作

示例中的表单已按RecordDate按降序排序 说只存在第一种形式,返回的列表将是

AA   11
BB   22
CC   33
DD   44

如果只有第一个和表单,则返回的列表将是

QQ   33
DD   22
EE   99
FF   66

因为最新形式的isUpdate(第二种形式)是no,返回的列表只是第二种形式的内容

前3个表格

QQ   33
DD   22
EE   99
FF   66
XX   00

因为最新形式的isUpdate(第3种形式)是肯定的,其内容将添加/替换最后一个列表。

说有这样的第五种形式

-------------------------
Name: District A
SchoolYear: 2000
RecordDate: 2/10/2000
IsUpdate: no

Participants
Name Location
TT   99
-------------------------

然后返回的数据就是

TT   99

3 个答案:

答案 0 :(得分:1)

我在这里看到了一个趋势...你想学习如何在你正在尝试的这个应用程序的上下文中使用数据库,或者你想发布问题并让我们告诉你答案吗?它可以以任何一种方式处理,但你应该非常清楚地发布你想要的东西。

这可能会变得复杂,因此您可能希望发布一个非常完整的架构。

答案 1 :(得分:1)

在我看来,数据库的设计似乎有些问题。

如果有三张桌子,那似乎更合乎逻辑。

一个人
此表应包含以下字段

  

Id(int,主键)
  名称(nvarchar)
  生物(nvarchar)
  位置(nvarchar)

一组
此表应包含以下字段

  

Id(int,主键)
  名称(nvarchar)   SchoolYear(日期时间)

关联人员和群组

  

标识
  GroupId的
  PERSONID
  RecordDate

这样,如果您需要将某人添加到某个组,只需将其插入到人员组表中即可。

如果你需要历史性的,你可以简单地在person-group表中添加一个字段来指示记录的状态(当前,删除,等等)

当前数据库的设计方式,一个人可能不在一个以上的组中。此外,对某个人群体的任何更改都是以破坏性方式进行的(除非您复制了您的人员, BAD )。

如果您需要以前人员所在群体的纸质记录,您可能还需要更多的桌子以保持历史性。

不应在数据库中使用IsUpdate字段,而应仅编辑数据。 MS Sql是一个数据库服务器,数据库是要更新的。

答案 2 :(得分:1)

您能否再次使用真实的数据值进行讨论? XX,AA等可能是“史密斯”,“琼斯”。他们每个人对于现有的集团,地点等价值有什么影响?

然后选择一个IsUpdate表单示例,并显示结果。然后为同一个表单切换到IsUpdate = false,并显示不同的结果?