Форум программистов, компьютерный форум, киберфорум
Delphi: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
 Аватар для edsjeka
8 / 8 / 7
Регистрация: 01.01.2016
Сообщений: 386

В главной таблице два поля связаны с одним и тем же справочником, возможно такое?

30.03.2016, 21:00. Показов 942. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Ситуация такая, есть главная таблица, по учету заправки лазерных картриджей, в ней есть поля: менеджер принявший картридж и менеджер выдавший картридж. Получается, что главная таблица связана двумя полями с одним справочником менеджеров отношениями 1 ко многим. Это вообще правильно или нет?
Почему спрашиваю, у меня не получается в одном запросе с джоинами вывести менеджера принявшего и менеджера выдавшего, я пока делаю второй запрос и тогда все получается, но это усложняет алгоритм. Но как сделать правильно? Есть мысль продублировать справочник менеджеров и тогда можно будет при одном запросе получать менеджера и принявшего и выдавшего, но это будет повтор одной и той же информации, думаю, это не очень верно. Как в этом случае сделать правильно?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
30.03.2016, 21:00
Ответы с готовыми решениями:

Связать в запросе 2 поля таблицы с одним справочником
Здравствуйте. Есть таблица (SAMPLES) в БД Firebird Embedded, 2 поля которой (например, в данном случае единицы измерения...

Найти и напечатать в столбик поля, начинающиеся и заканчивающиеся одним и тем же символом
нужно среди буквенных полей, содержащиеся в текстовой строке длинною 40 символов, найти и напечатать в столбик поля, начинающиеся и...

Почему два раза создаётся объект с ОДНИМ И ТЕМ ЖЕ ИМЕНЕМ?
#include <windows.h> #include <iostream> using namespace std; class arr{ public: arr(){ cout << "Вызов конструктора по...

14
 Аватар для Пытливый
3763 / 2267 / 705
Регистрация: 29.05.2013
Сообщений: 9,622
30.03.2016, 22:56
Все нормально, вполне допустимо, что вы один справочник используете в разных полях, вот только для каждого поля вам надо будет добавить свой датасет, каждый из них будет подключен к одной таблице, но работать они все будут асинхронно. Если же вы подключите все поля к одному датасету, то и работать они тоже будут синхронно.
0
 Аватар для ZfoxAK
670 / 560 / 242
Регистрация: 26.11.2012
Сообщений: 2,191
31.03.2016, 05:43
edsjeka, Скорее всего, не совсем правильно составил запрос. Что бы помогли покажи структуру главной таблице и справочника и текст уже созданного запроса
0
 Аватар для edsjeka
8 / 8 / 7
Регистрация: 01.01.2016
Сообщений: 386
31.03.2016, 08:23  [ТС]
Цитата Сообщение от ZfoxAK Посмотреть сообщение
покажи структуру главной таблице и справочника и текст уже созданного запроса
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
DataModule1.SQLQuery1.Close;
         DataModule1.SQLQuery1.SQL.Text:='SELECT cartridgi.IDCartridga, cartridgi.DatePriema, sprmodeleycartridgey.ModelCartridga, sprindexov.Indeks,'+
         ' sprklientov.NameKlient, cartridgi.Articul, sprstatusov.Status, sprmanager.Manager, sprmasterov.master, cartridgi.NumZayavki,'+
         ' cartridgi.komments, cartridgi.DateVidachi, sprmestrabot.mestorabot, cartridgi.daterabot, cartridgi.UchetVzp,'+
         ' cartridgi.DocVist, cartridgi.Nal_bn, sprpredpr.namepredpr, sprTipOpl.TipOpl'+
         ' FROM cartridgi'+
         ' INNER JOIN sprmodeleycartridgey ON cartridgi.IDModelCartridga = sprmodeleycartridgey.IDModelCartridga'+
         ' INNER JOIN sprindexov ON sprmodeleycartridgey.IDIndexa = sprindexov.IDIndexa'+
         ' INNER JOIN sprklientov ON cartridgi.IDKlienta = sprklientov.IDKlienta'+
         ' INNER JOIN sprstatusov ON cartridgi.IDstatusa = sprstatusov.IDStatusa'+
         ' INNER JOIN sprmanager ON cartridgi.IDManagerPrin = sprmanager.IDManager'+
         ' LEFT JOIN sprmestrabot ON cartridgi.IDMestaRabot = sprmestrabot.IDMestaRabot'+
         ' LEFT JOIN sprmasterov ON cartridgi.IDMastera = sprmasterov.IDmastera'+
         ' LEFT JOIN sprpredpr ON cartridgi.IDPredpr = sprpredpr.IDPredpr'+
         ' LEFT JOIN sprtipopl ON cartridgi.IDTipOpl = sprTipOpl.IDTipOpl'+
         ' WHERE DATE(cartridgi.DatePriema) BETWEEN "'+ds+'" AND "'+DS1+'"'+
         ' ORDER BY cartridgi.DatePriema DESC';
         DataModule1.SQLQuery1.Active:=true;
Delphi
1
2
3
4
5
6
7
idCart:=DataModule1.SQLQuery1.FieldValues['IDCartridga'];
                 DataModule1.SQLQuery2.Close;
                 DataModule1.SQLQuery2.SQL.Text:='SELECT cartridgi.IDCartridga, sprmanager.Manager,       cartridgi.IDManagerVidal'+
                 ' FROM cartridgi'+
                 ' INNER JOIN sprmanager ON cartridgi.IDManagerVidal = sprmanager.IDManager AND cartridgi.IDManagerVidal = sprmanager.IDManager'+
                 ' WHERE IDCartridga='+IntToStr(IDCart);
                 DataModule1.SQLQuery2.Active:=true;
Вот так я делаю, сначала общий запрос, там вытягиваю менеджера принявшего, а потом, чтобы найти менеджера выдавшего, делаю еще один запрос и там уже нахожу его по ID из главной таблицы.

И все бы хорошо, все работает. Но у меня очень долго заполняется таблица StringGrid данными. Вот я и думаю, может можно как-то упростить то, что я делаю, убрать вложенный запрос..
Миниатюры
В главной таблице два поля связаны с одним и тем же справочником, возможно такое?  
0
5962 / 4538 / 1094
Регистрация: 29.08.2013
Сообщений: 28,149
Записей в блоге: 3
31.03.2016, 09:26
Цитата Сообщение от edsjeka Посмотреть сообщение
о у меня очень долго заполняется таблица StringGrid данными
а при чем тут запрос?
данные ты уже получил, запрос отработал

покажи как ты заносишь данные в грид
0
 Аватар для edsjeka
8 / 8 / 7
Регистрация: 01.01.2016
Сообщений: 386
31.03.2016, 09:33  [ТС]
Да я понимаю, что запрос тут времени не забирает много, но просто он мне давно не нравится мне казалось, что я что-то неправильно тут делаю.

Добавлено через 2 минуты
Цитата Сообщение от qwertehok Посмотреть сообщение
покажи как ты заносишь данные в грид
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
j:=1;
    with  DataModule1.SQLQuery1 do    // цикл по
         begin
          First;
          while not Eof do
           begin
                AdvSG2.AddCheckBox(0, j, false, true);
 
               idCart:=DataModule1.SQLQuery1.FieldValues['IDCartridga'];
               AdvSG2.Cells[1,j]:=DataModule1.SQLQuery1.FieldValues['IDCartridga'];
 
               FormatSettings.ShortDateFormat:='dd.MM.yyyy';
 
               if DataModule1.SQLQuery1.FieldValues['DatePriema']<>NULL
                 then
                 begin
 
                    AdvSG2.Cells[2,j]:=DataModule1.SQLQuery1.FieldValues['DatePriema'];
                 end
                 else AdvSG2.Cells[2,j]:='-';
               AdvSG2.Cells[3,j]:=DataModule1.SQLQuery1.FieldValues['ModelCartridga'];
               AdvSG2.Cells[4,j]:=DataModule1.SQLQuery1.FieldValues['NameKlient'];
               if DataModule1.SQLQuery1.FieldValues['Manager']<>NULL
                 then
                 begin
 
                    AdvSG2.Cells[5,j]:=DataModule1.SQLQuery1.FieldValues['Manager'];
                 end
                 else AdvSG2.Cells[5,j]:='-';
               AdvSG2.Cells[6,j]:=DataModule1.SQLQuery1.FieldValues['Articul'];
               AdvSG2.Cells[7,j]:=DataModule1.SQLQuery1.FieldValues['Status'];
               AdvSG2.Cells[8,j]:=DataModule1.SQLQuery1.FieldValues['NumZayavki'];
               if DataModule1.SQLQuery1.FieldValues['Master']<>NULL
                 then
                 begin
 
                    AdvSG2.Cells[9,j]:=DataModule1.SQLQuery1.FieldValues['Master'];
                 end
                 else AdvSG2.Cells[9,j]:='-';
               AdvSG2.Cells[10,j]:=DataModule1.SQLQuery1.FieldValues['komments'];
               if DataModule1.SQLQuery1.FieldValues['DateVidachi']<>NULL
                 then
                 begin
 
               AdvSG2.Cells[11,j]:=DataModule1.SQLQuery1.FieldValues['DateVidachi'];
                 end
                 else AdvSG2.Cells[11,j]:='-';
               if DataModule1.SQLQuery1.FieldValues['MestoRabot']<>NULL
                 then
                 begin
 
               AdvSG2.Cells[12,j]:=DataModule1.SQLQuery1.FieldValues['MestoRabot'];
                 end
                 else AdvSG2.Cells[12,j]:='-';
 
                 idCart:=DataModule1.SQLQuery1.FieldValues['IDCartridga'];
                 DataModule1.SQLQuery2.Close;
                 DataModule1.SQLQuery2.SQL.Text:='SELECT cartridgi.IDCartridga, sprmanager.Manager, cartridgi.IDManagerVidal'+
                 ' FROM cartridgi'+
                 ' INNER JOIN sprmanager ON cartridgi.IDManagerVidal = sprmanager.IDManager AND cartridgi.IDManagerVidal = sprmanager.IDManager'+
                 ' WHERE IDCartridga='+IntToStr(IDCart);
                 DataModule1.SQLQuery2.Active:=true;
                   if DataModule1.SQLQuery2.FieldValues['IDManagerVidal']<>NULL
                 then
                 begin
 
               AdvSG2.Cells[13,j]:=DataModule1.SQLQuery2.FieldValues['Manager'];
                 end
                 else AdvSG2.Cells[13,j]:='-';
 
 
 
 
 
 
               if DataModule1.SQLQuery1.FieldValues['DateRabot']<>NULL
                 then
                 begin
 
               AdvSG2.Cells[14,j]:=DataModule1.SQLQuery1.FieldValues['Daterabot'];
                 end
                 else AdvSG2.Cells[14,j]:='-';
               AdvSG2.Cells[15,j]:=DataModule1.SQLQuery1.FieldValues['Indeks'];
               {AdvSG2.Cells[16,j]:=DataModule1.SQLQuery1.FieldValues['UchetVzp'];}
               if DataModule1.SQLQuery1.FieldValues['DocVist']=0
                 then
                   AdvSG2.AddCheckBox(16, j, false, true)
               else AdvSG2.AddCheckBox(16, j, true, true);
 
 
               AdvSG2.Cells[17,j]:=DataModule1.SQLQuery1.FieldValues['DocVist'];
               if DataModule1.SQLQuery1.FieldValues['TipOpl']<>NULL
                 then
                 begin
 
               AdvSG2.Cells[18,j]:=DataModule1.SQLQuery1.FieldValues['TipOpl'];
                 end
                 else AdvSG2.Cells[18,j]:='-';
               if DataModule1.SQLQuery1.FieldValues['NamePredpr']<>NULL
                then
                 begin
 
                    AdvSG2.Cells[19,j]:=DataModule1.SQLQuery1.FieldValues['NamePredpr'];
                 end
                 else AdvSG2.Cells[19,j]:='-';
 
 
               j:=j+1;
             Next;
           end;
 
         end;
0
5962 / 4538 / 1094
Регистрация: 29.08.2013
Сообщений: 28,149
Записей в блоге: 3
31.03.2016, 10:31
в каждое прохождение цикла вписать еще один запрос и спрашивать почему у него заполняется не так быстро как хочется

Чингачгука и Соколиного Глаза поймали белые и перед казнью заперли в сарае. На ТРЕТИЙ день заточения Соколиный Глаз заметил, что в сарае не хватает стены..
0
 Аватар для edsjeka
8 / 8 / 7
Регистрация: 01.01.2016
Сообщений: 386
31.03.2016, 10:38  [ТС]
Цитата Сообщение от qwertehok Посмотреть сообщение
в каждое прохождение цикла вписать еще один запрос
Вот поэтому я и завел эту тему. Как мне тогда можно получать менеджера выдавшего не включая запроса в цикл, если я не могу один и тот же справочник привязать к главной таблице два раза?
0
5962 / 4538 / 1094
Регистрация: 29.08.2013
Сообщений: 28,149
Записей в блоге: 3
31.03.2016, 10:44
Цитата Сообщение от edsjeka Посмотреть сообщение
если я не могу один и тот же справочник привязать к главной таблице два раза?
почему нельзя?

SQL
1
2
3
SELECT * FROM table1 t1
LEFT JOIN table2 t2 ON t1.id=t2id
LEFT JOIN table2 t22 ON t1.m_id=t22.m_id
Добавлено через 2 минуты
в конце концов можно данные первого запроса выгрузить во временную таблицу и к ней уже делать запрос
0
 Аватар для edsjeka
8 / 8 / 7
Регистрация: 01.01.2016
Сообщений: 386
31.03.2016, 11:19  [ТС]
Цитата Сообщение от edsjeka Посмотреть сообщение
в каждое прохождение цикла вписать еще один запрос
Ну да, без запроса в цикле почти в 10 раз быстрее получается, за 0,2с заполняется таблица
0
 Аватар для Пытливый
3763 / 2267 / 705
Регистрация: 29.05.2013
Сообщений: 9,622
31.03.2016, 11:49
SQL
1
 WHERE DATE(cartridgi.DatePriema) BETWEEN "'+ds+'" AND "'+DS1+'"'
А вот вставляя дату в запрос строкой вас могут ждать неожиданные сюрпризы. Например, некоторые базы воспринимают дату всегда как Дата и Время. И если мы передаем 01.01.2016 для базы это будет 01.01.2016 00:00:00 и это не страшно пока вы не захотите подставить такие даты в проверку диапазона. Начальный диапазон будет верен, а вот конечный будет заканчиваться не концом суток, а их началом.
К тому-же есть еще формат представления данных - вы можете передавать дату в формате dd.mm.yyyy а база может работать с форматом mm.dd.yyyy
0
 Аватар для edsjeka
8 / 8 / 7
Регистрация: 01.01.2016
Сообщений: 386
31.03.2016, 11:56  [ТС]
Цитата Сообщение от Пытливый Посмотреть сообщение
К тому-же есть еще формат представления данных - вы можете передавать дату в формате dd.mm.yyyy а база может работать с форматом mm.dd.yyyy
Так и получилось и поэтому у меня вставлено:
Delphi
1
FormatSettings.ShortDateFormat:='dd.MM.yyyy';
.
И после этого все свелось к одинаковому формату.
0
5962 / 4538 / 1094
Регистрация: 29.08.2013
Сообщений: 28,149
Записей в блоге: 3
31.03.2016, 12:19
а если параметры использовать в запросе, а потом делать так
query.params.parambyname().asDate:=StrTo Date(Edit1.Text);
то все будет ок (Sqlite и MSSQL)
0
 Аватар для edsjeka
8 / 8 / 7
Регистрация: 01.01.2016
Сообщений: 386
31.03.2016, 16:08  [ТС]
Цитата Сообщение от qwertehok Посмотреть сообщение
1
2
3
SELECT * FROM table1 t1
LEFT JOIN table2 t2 ON t1.id=t2id
LEFT JOIN table2 t22 ON t1.m_id=t22.m_id
Это нужно сделать еще одно ключевое поле и по нему связывать, правильно?
0
5962 / 4538 / 1094
Регистрация: 29.08.2013
Сообщений: 28,149
Записей в блоге: 3
31.03.2016, 16:11
что значит "нужно сделать"?
и что значит "ключевое поле"?

нужно - делай
ключевое - так ключевое
но соединять таблицы можно по любому полю
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
31.03.2016, 16:11
Помогаю со студенческими работами здесь

Если возможно, с поля (k, l) одним ходом коня попасть на поле (m, n)
Поле шахматной доски определяется парой натуральных чисел, первое из которых задает номер вертикали, а второе - номер горизонтали. Даны...

Обмен одним справочником номенклатуры между двумя Бухгалтериями 8.2
Здравствуйте! Подскажите, пожалуйста, каким образом настроить синхронизацию одного справочника номенклатуры между двумя Бухами 8.2...

Требуется если возможно одним ходом ферзя попасть с одного поля на другое
Кто нибудь знает как можно сделать программу другим способом или облегчить вот эту: Поле шахматной доски определяется парой натуральных,...

Как скролить одним скролом два текстовых поля?
Есть два текстовых поля(Multiline=true) и ScrollBar. Как мне скролить два поля одновременно?

Можно ли выучить С#, пользуясь одним только справочником msdn, достаточно ли этого?
Возник такой вопрос: а можно ли выучить С#,пользуясь одним только справочником mcdn, достаточно ли этого? Почему? Заранее спасибо...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru