сложный SQL-запрос - объединить или заменить группы - PullRequest
0 голосов
/ 26 марта 2009

Я создаю школьный сайт и застрял в этой проблеме.

База данных 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)

Фактически бумажная форма выглядит так, она обновляется в течение года Не допускайте дублирования имен участников (People.Name) в одной форме (GroupRecords)

-------------------------
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 - да, то список возвращаемых людей должен объединиться со списком предыдущей записи (так что если IsUpdate - нет: заменить, если IsUpdate - да: объединить)

, поэтому, если запрос GroupRecords.Name = 'Район A' И 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 в последней форме (второй форме) - нет, возвращаемый список будет просто содержимым во 2-й форме

первые 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 ]

1 голос
/ 26 марта 2009

На мой взгляд, что-то не так с дизайном базы данных.

Было бы намного логичнее, если бы было три таблицы.

Один на человека
Эта таблица должна иметь следующие поля

Id (int, первичный ключ)
Имя (nvarchar)
Био (нварчар)
Расположение (nvarchar)

Один для групп
эта таблица должна иметь следующие поля

Id (int, первичный ключ)
Имя (нварчар) SchoolYear (datetime)

Один, чтобы связать Персоны и группы

Id
GroupID
PersonId
RecordDate

Таким образом, если вам нужно добавить человека в группу, вы просто вставляете его в таблицу групп людей.

Если вам нужна хронология, вы можете просто добавить поле в таблицу групп лиц, в котором указано состояние записи (текущая, удаленная и т. Д.)

При проектировании текущей базы данных один человек может входить не более чем в одну группу. Кроме того, любые изменения в группе лиц производятся деструктивным образом (если только вы не дублируете свои лица, что составляет BAD ).

Если вам нужен бумажный след группы, в которой ранее были люди, вам также может понадобиться больше таблиц, чтобы сохранить исторические данные.

Вместо использования поля IsUpdate в базе данных, данные должны быть просто отредактированы. MS Sql является сервером баз данных, и базы данных должны обновляться.

1 голос
/ 26 марта 2009

Можете ли вы снова поговорить с реалистичными значениями данных? XX, AA и т. Д. Могут быть "Смит", "Джонс". Что может иметь каждый из них для существующих значений Group, Location и т. Д .?

Затем возьмите один пример формы IsUpdate и покажите, каков будет результат. Затем для той же формы переключитесь на IsUpdate = false и покажите другой результат?

1 голос
/ 26 марта 2009

Я вижу тенденцию здесь ... Вы хотите узнать, как работать с базами данных в контексте этого приложения, над которым вы пытаетесь работать, или вы хотите оставлять вопросы и предлагать нам ответы? Это может быть обработано в любом случае, но вы должны опубликовать довольно четко, что вы хотите.

Вероятно, это будет сложно, поэтому вы можете опубликовать довольно полную схему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...