Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

SQL для 3-х таблиц ? [D7, FireBird]


Страницы:   1 2

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 (
   ID,        -
   Person_ID, - ссылка на препода
   Name_WT,   - наимен типа (преподаватель, концертмейстер)
   Norma_ID_H - на норму часов
 )
 Хотя и здесь нарушается 1NF- Name_WT
 Разбить конечно можно, но надо не забывать, что есть еще другие должности:
  - совместители, административно управленческий персонал (АУП), дежурные и т.д. И их надо када-то определять.


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]

выбрать людей или их часы ?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо