![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
SQL для 3-х таблиц ? [D7, FireBird]
worldmen © (2005-09-19 12:49:00)Дано, таблицы (упрощенно):
Т1- таблица клиентов. Поля: idkl, Fam.
Т2, Т3- таблицы данных. Поля: id, data1, data2
Эти таблицы (Т2, Т3) одинаковые.
Нужно составить SQL таким образом: Т1 использует данные из Т2, но если есть по этому клиенту строка в Т3 - использовать данные из Т3.
worldmen (2005-09-28 09:14:00) [1]>ANB © (27.09.05 13:02) [35]
>4. Штат (кто, где) Staff (
>Person_ID,
>Post_ID,
>Work_Type_ID,
>Оклад, норма часов и прочая бредятина
>)
Структура таблицы Staff нарушает 1-ю нормальную форму.
1-я нормальная форма( 1NF): Сущность находится в 1NF только тогда, когда все атрибуты содержат атомарные значения. Среди атрибутов не должно встречаться повторяющихся групп.
Например для Person_ID - Work_Type_ID имеет два значения.
Так, что Work_Type_ID, Норму часов и прочую бредятину надо в другую таблицу.
Для Норма_часов надо:
1. ID_H
2. Dnevn - на дневном отделении
3. Zaoch - на заочном отделении.
Из-за этого надо переделывать >Work_Type (ID, Name ...)
Эти троеточия как раз самые главные. И надо подумать, что туда подставить.
Предлагаю так:
Work_Type (Хотя и здесь нарушается 1NF- Name_WT
ID, -
Person_ID, - ссылка на препода
Name_WT, - наимен типа (преподаватель, концертмейстер)
Norma_ID_H - на норму часов
)
Разбить конечно можно, но надо не забывать, что есть еще другие должности:
- совместители, административно управленческий персонал (АУП), дежурные и т.д. И их надо када-то определять.
worldmen (2005-09-27 19:10:00) [2]
> Sergey13 © (27.09.05 12:10) [34]
> Тремя таблицами тут не обойтись, даже заная SQL в cсовершенстве
У меня их 25, и будет больше. Структура согласен - не супер, но все работает. И Ведомость и План. Боюсь, что будет тормозить.
И ошибок пока небыло с базой.
> ANB © (27.09.05 13:02) [35]
Псижу подумаю
> ANB © (27.09.05 13:02) [35]
> почитай умные книжки по теории БД.
Читал - О нормальных формах.
ANB (2005-09-27 13:02:00) [3]
> worldmen © (27.09.05 12:03) [33]
Примерно так :
Имеем :
1. Список людей пусть Person (ID, Fam, Name . . .)
2. Список должностей Post (ID, Name ...)
3. Справочник типов должности Work_Type (ID, Name ...)
Вот сюда и забиваешь : '1-я основ. проф. ', '2-я основ. проф. ' . . .
4. Штат (кто, где) Staff (
Person_ID,
Post_ID,
Work_Type_ID,
Оклад, норма часов и прочая бредятина
)
ЗЫ. SQL тут и правда не причем, нужно сесть и с карандашем и бумагой все продумать. Если практики маловато (я таких книжек не читал, все само дошло), почитай умные книжки по теории БД.
Sergey13 (2005-09-27 12:10:00) [4]2[33] worldmen © (27.09.05 12:03)
Чем больше читаю, тем сильнее мне кажется, что ты плохо спроетировал БД (или точнее недоработал в этом направлении). Тремя таблицами тут не обойтись, даже заная SQL в cсовершенстве.
Все исключительно ИМХО.
worldmen (2005-09-27 12:03:00) [5]> ANB © (23.09.05 11:16) [27]
> Преподаватель - должность - это обычная линковка
- это понятно, но я не смог представить, в деталях, какможно забить туда реальные данные. Например такие:
Иванов И.И.
-преподаватель 14-го разряда, (1-я основ. проф.) - 3.55 руб/ч. оклад 250 руб.
-концертмейстер 16-го разряда (2-я основ. проф.)- 4.85 руб/ч. оклад 311 руб
-классное руководство - 10% (допол. должн.)
-руководитель ПЦК - 12% (допол. должн.)
-проверка тетрадей -15% (допол. должн.)
-методист 14% (допол. проф.)
Для дополн. должности считается процент от максимального оклада преподавателя. В данном случае 311 руб.
Os (2005-09-23 15:39:00) [6]Категорически согласен :)
ANB (2005-09-23 12:01:00) [7]
> Os © (23.09.05 11:53) [30]
- зато int даст возможность завести локаповое поле и выбирать значение в гриде из комбобоксика. Это так прикольно.
А если серьезно, то текст, во первых - несколько длиннее, во вторых больше граблей с его изменением или неправильным написанием.
Os (2005-09-23 11:53:00) [8]
> - совсем некошерно.
Я и не говорил что это самый лучший вариант, Int веселее но не наглядно.
ANB (2005-09-23 11:29:00) [9]
> В данном случае IdRaboti varchar(20)
- совсем некошерно.
Os (2005-09-23 11:26:00) [10]
> А как тогда выбрать по id какая из професий Основная, Дополнительная,
> Препод
Select ... from .... where id=:IdPrepoda and IdRaboti='Основная'
В данном случае IdRaboti varchar(20)
Вариантов много, хочешь список всех его професий хочешь отдельно. Все зависит от реализации класса. Данные из таблицы можно рассматривать как свойства класса, а методы в зависимости какой смысл вложить в класс. По крайней мере локализация данных и ошибок обеспечена. Плата за это дополнительный код и возможно снижение быстродействия.
ANB (2005-09-23 11:16:00) [11]
> Os © (22.09.05 12:27) [25]
- транслитом поля обзывать некошерно.
> worldmen © (22.09.05 18:41) [26]
Преподаватель - должность - это обычная линковка (многие к многим). Тип связи (тип должности) указываешь в отдельном поле и можешь учитывать как константой, так и сделать ссылку на справочник (это более кузяво). Если нужно выбрать только основные (препод) - в запрос втыкаешь фильтр по типу.
Совет - грамотно спланируй индексы, не забудь сделать их составными иначе, когда база вырастет, все начнет тормозить.
worldmen (2005-09-22 18:41:00) [12]
> Id
> IdPrepoda
> IdRaboti - Основная, Дополнительная, Препод и т.д.
> Status - дневная, заочная ....
> Oklad
А как тогда выбрать по id какая из професий Основная, Дополнительная, Препод ?
Os (2005-09-22 12:27:00) [13]Структура :(((
Завтра кто-то возмет еще нагрузку и перелопачивай всю базу.
Я бы создал tabl. Должностей и туда писал бы
Id
IdPrepoda
IdRaboti - Основная, Дополнительная, Препод и т.д.
Status - дневная, заочная ....
Oklad
.....
и аналогично табель.
Все легко извлекается и никакого гемороя
worldmen (2005-09-22 10:48:00) [14]Табл. подразделений. Например:
1. АУП - административно управл. персонал
2. Преподаватели - (каждый преподаватель имеет две должности - Преподаватель и Концертмейстер.)
Не путать подразделения с должностями.
3. Совместители
4. ...
CREATE TABLE Podrazd (
ID_pdr INTEGER NOT NULL, - id подразделения
Name_Pdr VARCHAR(20), - назв. подр
Grafik INTEGER, - график работы
PRIMARY KEY (ID_pdr)
);
Табл. - КЛИЕНТОВ (Т1) (учителей)
CREATE TABLE Klient (
ID_KL INTEGER NOT NULL,
ID_pdr INTEGER NOT NULL,- в какое подраз входит
Tab_nom VARCHAR(20), - табельный
Fam VARCHAR(20), - фамилия
Imy VARCHAR(20),
Otch VARCHAR(20),
PRIMARY KEY (ID_KL),
FOREIGN KEY (ID_pdr)
REFERENCES Podrazd
);
Таблица - у какого клиента какая должность
Поле Prof_1 - для id преподавателя,
а Prof_2 - для id концертмейстера
Dop1..4 - дополнительная нагрузка (4 вида) выражается в % от оклада.
CREATE TABLE Kl_Prof (
ID_KL INTEGER NOT NULL,
Prof_1 INTEGER,
Prof_2 INTEGER,
Dop1 INTEGER,
Dop2 INTEGER,
Dop3 INTEGER,
Dop4 INTEGER,
FOREIGN KEY (ID_KL)
REFERENCES Klient
);
ПЕДНАГРУЗКА - Т2
CREATE TABLE PedNagr ( - Пед. нагрузка в часах на год (плановое)
ID_KL INTEGER NOT NULL,
Dn_Konc INTEGER, - дневная
Dn_Ped INTEGER,
Zao_Ped INTEGER, - заочная
Zao_Konc INTEGER,
Year INTEGER,
FOREIGN KEY (ID_KL)
REFERENCES Klient
);
Каждый преподаватель имеет 2-е должности - Преподаватель и Концертмейстер.
ВЕДОМОСТЬ - Т3 - подается ежемесячно.
CREATE TABLE Vedomost (
ID_KL INTEGER NOT NULL,
PedH INTEGER, - часы дневного отделения педагогические
KoncH INTEGER, - ч. д. о. концертмейстерские
ZPedH INTEGER, - заочное отд. ...
ZKoncH INTEGER, - ...
FOREIGN KEY (ID_KL)
REFERENCES Klient
);
У должностей - Преподаватель и Концертмейстер есть разряды.
например:
разряд | преп. | конц. | оклад
| грн/ч | грн/ч |
----------------------------------
14 3.50 3.15 280
15 4.20 3.90 310
Но табл. я оформил по другому:
разряд | грн/ч | оклад
--------------------------
14 3.50 280
14 3.15 280
15 4.20 310
15 3.90 310
Так как Учитель может иметь разряд 14 Преподавателя и 15 Концертмейстера.
CREATE TABLE Kategor ( - табл. категорий
ID_KT INTEGER NOT NULL,
ID_Pdr INTEGER NOT NULL,
Razr VARCHAR(20),
Kat_Name VARCHAR(20),
Hour FLOAT,
Oklad INTEGER,
PRIMARY KEY (ID_KT),
FOREIGN KEY (ID_Pdr)
REFERENCES Podrazd
);
Не сильно загрузил? :)
worldmen (2005-09-21 19:04:00) [15]SQL работает, пока.... Я в базу мало людей еще ввел.
Завтра принесу структуру БД.
ANB (2005-09-21 17:19:00) [16]
> worldmen © (21.09.05 16:56) [21]
- нехорошо сделал. DATA_NOT_FOUND в FB не бывает ? Вообще то для скалярных запросов лучше агрегатные функции для надежности использовать. Плюс, твоя конструкция будет жутко тормозить.
Так кто лежит в T1 - преподаватели или должности ?
worldmen (2005-09-21 16:56:00) [17]
> ANB © (21.09.05 14:49) [20]
>
> > select idkl, hour1, hour2, hour3, hour4
> > from T1
> - странно, вроде часов в T1 у тебя не было
Действительно небыло. Я в реальном запросе круче сделал. А точнее:
select idkl,
(select hour1 from T2 where ....) hour1 ,
(select hour2 from T2 where ....) hour2 ,
(select hour3 from T2 where ....) hour3 ,
(select hour4 from T2 where ....) hour4 ,
from T1
where not exists (select 1 from T3 where T1.idkl=T3.idkl and {с учетом месяца})
У меня там еще преподаватель может иметь две должности. Поэтому так сложно.
ANB (2005-09-21 14:49:00) [18]
> select idkl, hour1, hour2, hour3, hour4
> from T1
- странно, вроде часов в T1 у тебя не было . . .
worldmen (2005-09-21 11:45:00) [19]Я вас, видимо, ввел в заблуждение. Мне надо было не обязательно одним Select-ом выбрать.
У меня получилось. Спасибо > ANB ©.
Вот что у меня вышло:
сдесь я выбираю тех, кто не вошел в ведомость на этот месяц, т.е. часы вычисляются по плану:
select idkl, hour1, hour2, hour3, hour4
from T1
where not exists (select 1 from T3 where T1.idkl=T3.idkl and {с учетом месяца})
А потом делаю обыкновенный select из T3 (ведомости). И все. Всем спасибо. Я много узнал интересного.
ANB (2005-09-20 19:23:00) [20]
> worldmen © (20.09.05 17:41) [17]
выбрать людей или их часы ?