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

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

получить несколько столбцов для одного поля [D5, IB6.x]


porter ©   (2008-01-07 02:22:00) 

Для упрощение вопроса возьму 2 абстрактные таблицы
Главная: Испытуемый; Подчиненная: Параметр.

Испытуемый
PK   ID
     Name
     Param_ID
     Value

Параметр
PK   ID
     parName

Из них надо получить таблицу вида:
--------------------------------------------------------
Name |  parName1 | parName2 | parName3 | ...
--------------------------------------------------------
Имя   |     Value     | Value

где parName1, parName2 -это значения parName, удовлетворяющие определённым условиям.


porter   (2008-01-07 21:40:00) [1]

Я уже осознал :-)


PEAKTOP   (2008-01-07 21:10:00) [2]

> А имя таблицы в качестве предиката - потому что у IBExpert'а
> автокомплит удобный


Автокомплит нормально понимает предикаты. Эту функциональность Саша Хвастунов еще два года назад реализовал.


porter   (2008-01-07 20:10:00) [3]

Спасибо, циферки стали разные :-)
where  "MarkSheetType".ID = 1  -- он всегда будет равен "1"- эт в целях проверки. Параметры ещё негде в запрос вводить.
А имя таблицы в качестве предиката - потому что у IBExpert'а автокомплит удобный


PEAKTOP   (2008-01-07 19:46:00) [4]

На хрена это ?

....
(select FIRST 1 "MarkSheets"."Mark"
from    "MarkSheets", "MarkSheetType"
where "MarkSheetType".ID = 1-- он всегда будет равен "1"
 AND "MarkSheetType".ID = "MarkSheets"."MarkSheetType_ID"-- это уже бессмысленно
 AND  "MarkSheets"."Class_ID" = 3
 and  "MarkSheets"."Discipline_ID" = 2) AS PAR1,
....


А так ?

SELECT ST.SURNAME
 ,(SELECT FIRST 1 M.MARK
   FROM   MARKSHEETS M
   WHERE  (M.MARKSHEETTYPE_ID = 1)
     AND  (M.STUDENT_ID       = ST.ID)
     AND  (M.DISCIPLINE_ID    = 2)
   )AS PAR1

 ,(SELECT FIRST 1 M.MARK
   FROM   MARKSHEETS M
   WHERE  (M.MARKSHEETTYPE_ID = 2)
     AND  (M.STUDENT_ID       = ST.ID)
     AND  (M.DISCIPLINE_ID    = 2)
   )AS PAR1

 ,(SELECT FIRST 1 M.MARK
   FROM   MARKSHEETS M
   WHERE  (M.MARKSHEETTYPE_ID = 3)
     AND  (M.STUDENT_ID       = ST.ID)
     AND  (M.DISCIPLINE_ID    = 2)
   )AS PAR1
FROM   STUDENT ST
WHERE (ST.CLASS_ID = 3)


И еще. Перестань пользовать имя таблицы в качестве предиката к имени поля. Для этого есть псевдонимы (FROM "TableName" T1). В FireBird-е версий 1.5.4 и 2.0 это считается минимум не кошерным, а в версии 2.1 ты можешь в некоторых случаях пойти лесом с таким запросом. В версии 2.5 разработчики обещали вообще снести такой синтаксис навсегда.


porter   (2008-01-07 19:08:00) [5]

Приведу для ясности реальные таблицы:
1. Ведомость:
CREATE TABLE "MarkSheets" (
   ID                  TINTEGER_NOTNULL NOT NULL,
   "MarkSheetType_ID"  TINTEGER_NOTNULL,
   "Manager_ID"        TINTEGER_NOTNULL,
   "Class_ID"          TINTEGER_NOTNULL,
   "Student_ID"        TINTEGER_NOTNULL,
   "Discipline_ID"     TINTEGER_NOTNULL,
   "Mark"              TINTEGER_NOTNULL,
   "DocumentDate"      TTIMESTAMP,
   "Number"            TINTEGER_CANNULL
);


2. Студенты:
CREATE TABLE "Student" (
   ID            TINTEGER_NOTNULL NOT NULL,
   "Class_ID"    TINTEGER_NOTNULL,
   "Surname"     TVARCHAR_NOTNULL,
   "Name"        TVARCHAR_NOTNULL,
   "Patronymic"  TVARCHAR_NOTNULL,
   "Birthday"    TDATE,
   "Address"     TVARCHAR_NOTNULL,
);

Пытаюсь запросом сформировать ведомость оценок (Mark) для одного класса по одному предмету за 4 четверти. Таким запросом:
select "Student"."Surname",
(select FIRST 1 "MarkSheets"."Mark" from "MarkSheets", "MarkSheetType" where "MarkSheetType".ID = 1 AND "MarkSheetType".ID = "MarkSheets"."MarkSheetType_ID" AND "MarkSheets"."Class_ID" = 3 and "MarkSheets"."Discipline_ID" = 2) AS PAR1,
(select FIRST 1 "MarkSheets"."Mark" from "MarkSheets", "MarkSheetType" where "MarkSheetType".ID = 2 AND "MarkSheetType".ID = "MarkSheets"."MarkSheetType_ID" AND "MarkSheets"."Class_ID" = 3 and "MarkSheets"."Discipline_ID" = 2) AS PAR2,
(select FIRST 1 "MarkSheets"."Mark" from "MarkSheets", "MarkSheetType" where "MarkSheetType".ID = 3 AND "MarkSheetType".ID = "MarkSheets"."MarkSheetType_ID" AND "MarkSheets"."Class_ID" = 3 and "MarkSheets"."Discipline_ID" = 2) AS PAR3,
(select FIRST 1 "MarkSheets"."Mark" from "MarkSheets", "MarkSheetType" where "MarkSheetType".ID = 4 AND "MarkSheetType".ID = "MarkSheets"."MarkSheetType_ID" AND "MarkSheets"."Class_ID" = 3 and "MarkSheets"."Discipline_ID" = 2) AS PAR4
from "Student" where ("Student"."Class_ID" = 3)


Получаю набор данных, вида:
Фаимилия | Четверть1 | Четверть 2 | ...
Иванов     |       5       |       3
Петров     |       5       |       3
Сидаров   |       5       |       3

Фактически должен получится набор вида:
Фаимилия | Четверть1 | Четверть 2 | ...
Иванов     |       5       |       3
Петров     |       4       |       5
Сидаров   |       2       |       4


Johnmen   (2008-01-07 19:00:00) [6]

Кстати о терминологии - перепутаны главная и подчиненная.


PEAKTOP   (2008-01-07 18:57:00) [7]

> Подскажите, что я не так делаю

У тебя ошибка в 17-й строке.


porter   (2008-01-07 18:37:00) [8]


> PEAKTOP ©   (07.01.08 04:15) [3]
>
> http://delphiplus.org/articles/ib/firebird-2-full-capability/1/index.
> html

Спасибо, кажется, статья указала правильное направление.
Остался один вопрос:
Использую конструкцию для Firebird 1.5  
SELECT TMC.NAME,
   (SELECT FIRST 1 TQ.QUANT FROM TABL$P_TMC_QUANT TQ WHERE(TQ.TMC_ID = TMC.ID)AND(TQ.PLACE_ID = '1')) AS QUANT_1
и т.д.

При этом получается таблица вида:
--------------------------------------------------------
Name |  parName1 | parName2 | parName3 | ...
--------------------------------------------------------
Имя1   |     Value1     | Value 2   | Value 3
Имя2   |     Value1     | Value 2   | Value 3
Имя3   |     Value1     | Value 2   | Value 3

Т.е. значения Value для каждой колонки parName берутся по первому полученному. Причиной, видимо, FIRST 1.
Подскажите, что я не так делаю


PEAKTOP   (2008-01-07 04:15:00) [9]

http://delphiplus.org/articles/ib/firebird-2-full-capability/1/index.html


DrPass   (2008-01-07 02:35:00) [10]

Средствами SQL на IB6.x никак. На FB1.5 и выше можно сделать ХП, которая динамически сделает запрос, выполнит его через EXECUTE STATEMENT и вернет искомый датасет. Это анальный способ.
Неанальный, действующий и на IB6, и на всех FB - взять генератор отчетов (например, FastReport), и сделать там кросс-отчет по этим табличкам.
P.S. Использование IB6.x - это тоже анальный способ создания программ. Есть масса причин заменить ее на FB, и нет ни одной, чтобы ее использовать...


turbouser   (2008-01-07 02:31:00) [11]

Это возможно сделать только если на клиенте генерировать текст запроса.


Наверх

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