Помогите модифицировать select
-
- Заслуженный разработчик
- Сообщения: 644
- Зарегистрирован: 15 фев 2005, 11:34
Индексы я потом вручную удаляю с помощью IBExpert, так что лишних индексов нет. Просто база рисовалась в Design-ере.kdv писал(а):мрак полный. на таблице ПК, и тут же по нему сделан уникальный индекс. FK - и опять вручную создан индекс. Зачем? Про джойны не знаем, и т.п.
Купи себе книжку по
1. Firebird (Хелен Борри, свежак).
2. по проектированию баз, что-нибудь.
Про join - не было задачь, что бы их применять. Конечно если бы было несколько подряд идуших объединений WHERE AND ... AND ... и был бы смысл то нужно применять join. А в таком select очень тяжело увидеть join
Код: Выделить всё
SELECT COALESCE( SUM(
(SELECT COUNT(DISTINCT(CS.CLIENTFK)) FROM CLIENTS2SUBJECTS CS WHERE
CS.SUBJECTFK = (
SELECT FIRST 1 SUBJECTID
FROM SUBJECTS WHERE COURSEFK=C.COURSEID ORDER BY (select count(*) from clients2subjects c2s where c2s.subjectfk=SUBJECTS.subjectid) DESC
) AND (
SELECT COUNT(*) FROM DEDUCTIONS D WHERE D.CLIENTFK=CS.CLIENTFK AND D.COURSEFK=C.COURSEID AND D."DATE"<=1136062799)=0
) ), 0)
FROM COURSES C WHERE
(SELECT COUNT(*) FROM SUBJECTS WHERE COURSEFK=C.COURSEID)>0 AND
(( 1133384400 BETWEEN C.COURSESTARTDATE AND C.COURSEENDDATE ) OR ( 1136062799 BETWEEN C.COURSESTARTDATE AND C.COURSEENDDATE ))
AND DIRDEPARTMENTFK=2
да ты шо!Про join - не было задачь, что бы их применять.

-
- Заслуженный разработчик
- Сообщения: 644
- Зарегистрирован: 15 фев 2005, 11:34
Так статистика-то в вашем итоге неправильная. В моем правильная. Следовательно в вашем подходе ошибка.kdv писал(а):да ты шо!Про join - не было задачь, что бы их применять.один мой знакомый говорил - если ты не знаешь join, то ты фактически не знаешь sql. Вот у тебя в запросе какие то подозрительные in (select), субселекты, субселекты с first, субселекты в where, и т.п. То есть, мешанина такая, что возникают сомнения в наличии смысла даже не вникая. Уж извини.
Код: Выделить всё
SELECT
C.COURSEID, C.GROUPNUMBER,
(SELECT COUNT(DISTINCT(CS.CLIENTFK)) FROM CLIENTS2SUBJECTS CS
WHERE
CS.SUBJECTFK IN (SELECT SUBJECTID FROM SUBJECTS WHERE COURSEFK=C.COURSEID)
) AS "COUNT"
FROM
COURSES C
WHERE
(SELECT COUNT(*) FROM SUBJECTS WHERE COURSEFK=C.COURSEID)>0 AND
(( 1133384400 BETWEEN C.COURSESTARTDATE AND C.COURSEENDDATE ) OR
( 1136062799 BETWEEN C.COURSESTARTDATE AND C.COURSEENDDATE )) AND
C.DIRDEPARTMENTFK=2
ORDER BY C.GROUPNUMBER
Код: Выделить всё
COURSEID GROUPNUMBER COUNT
80 40 29
111 40/с1 2
85 45 30
88 46В 26
108 47 25
159 47с 2
89 48 28
90 49Д 19
119 51 27
123 52Д 21
129 53 28
128 54В 24
151 55 6
154 56Д 10
158 57 13
175 58В 2
-
- Заслуженный разработчик
- Сообщения: 644
- Зарегистрирован: 15 фев 2005, 11:34
Вот упертый, беда прям... Тебе сказано убери нафиг нумерики из ключей... я накатил твой скрипт на одну из своих игровых БД, она в первом диалекте и твои нумерики стали лихо дабл пресижнами, теперь я начинаю джойнить это дело... дальше амбиснять?Так статистика-то в вашем итоге неправильная. В моем правильная. Следовательно в вашем подходе ошибка.
Хотя я не знаю где ты 293 откопал...
Например запрос
Код: Выделить всё
select cs.clientfk, count(*)
from courses c, Subjects s, Clients2Subjects cs
where s.coursefk = c.courseid
and s.subjectid = cs.subjectfk
and c.coursestartdate <= 1136062799
and c.courseenddate >= 1133384400
and C.DIRDEPARTMENTFK=2
group by cs.clientfk
Plan
PLAN SORT (JOIN (C NATURAL,S INDEX (IDX_SUBJECTS1),CS INDEX (IDX_CLIENTS2SUBJECTS3)))
Adapted Plan
PLAN SORT (JOIN (C NATURAL,S INDEX (IDX_SUBJECTS1),CS INDEX (IDX_CLIENTS2SUBJECTS3)))
------ Performance info ------
Prepare time = 10ms
Execute time = 80ms
Avg fetch time = 3,48 ms
Current memory = 895 688
Max memory = 954 320
Memory buffers = 2 048
Reads from disk to cache = 39
Writes from cache to disk = 0
Fetches from cache = 1 462

Сделал ключевые поля типа Integer. Backup/Restore и все равно мой селект возврашает 292, а ваш возврашает 293.
Если проссумировать результат по полю COUNT, то получится 292.
возврашает не то что мне нужно. Давайте отойдем от суммарной статистики. Попробуйте написать селект, который возвратит сколько уникальных человек учится на каждом курсе. У меня этот селектselect cs.clientfk, count(*)
from courses c, Subjects s, Clients2Subjects cs
where s.coursefk = c.courseid
and s.subjectid = cs.subjectfk
and c.coursestartdate <= 1136062799
and c.courseenddate >= 1133384400
and C.DIRDEPARTMENTFK=2
group by cs.clientfk
Код: Выделить всё
SELECT
C.COURSEID, C.GROUPNUMBER,
(SELECT COUNT(DISTINCT(CS.CLIENTFK)) FROM CLIENTS2SUBJECTS CS
WHERE
CS.SUBJECTFK IN (SELECT SUBJECTID FROM SUBJECTS WHERE COURSEFK=C.COURSEID)
) AS "COUNT"
FROM
COURSES C
WHERE
(SELECT COUNT(*) FROM SUBJECTS WHERE COURSEFK=C.COURSEID)>0 AND
(( 1133384400 BETWEEN C.COURSESTARTDATE AND C.COURSEENDDATE ) OR
( 1136062799 BETWEEN C.COURSESTARTDATE AND C.COURSEENDDATE )) AND
C.DIRDEPARTMENTFK=2
ORDER BY C.GROUPNUMBER
да наплюйте Вы на эти join-ы! Это все чтоб мозги запудрить придумано.avenger писал(а):все равно мой селект возврашает 292, а ваш возврашает 293.возврашает не то что мне нужно.select cs.clientfk, count(*)
from courses c, Subjects s, Clients2Subjects cs
where s.coursefk = c.courseid
and s.subjectid = cs.subjectfk
and c.coursestartdate <= 1136062799
and c.courseenddate >= 1133384400
and C.DIRDEPARTMENTFK=2
group by cs.clientfk
пробовать и думать не охота. Чуть модифицирую запрос Ivan_Pisarevskyavenger писал(а):Попробуйте написать селект, который возвратит сколько уникальных человек учится на каждом курсе.
Код: Выделить всё
select C.COURSEID, C.GROUPNUMBER, count(distinct CS.CLIENTFK)
from courses c, Subjects s, Clients2Subjects cs
where s.coursefk = c.courseid
and s.subjectid = cs.subjectfk
and c.coursestartdate <= 1136062799
and c.courseenddate >= 1133384400
and C.DIRDEPARTMENTFK=2
group by 1, 2
-
- Заслуженный разработчик
- Сообщения: 644
- Зарегистрирован: 15 фев 2005, 11:34
Код: Выделить всё
select c.courseid, count(distinct cs.clientfk)
from courses c, Subjects s, Clients2Subjects cs
where s.coursefk = c.courseid
and s.subjectid = cs.subjectfk
and c.coursestartdate <= 1136062799
and c.courseenddate >= 1133384400
and C.DIRDEPARTMENTFK=2
group by c.courseid
-
- Заслуженный разработчик
- Сообщения: 644
- Зарегистрирован: 15 фев 2005, 11:34
Еще, блин, один ламер объявился, который сольет все в универсальное отношение, чтоб без джойнов и будет везде потом вопить какой файрберд тормознутый и глючный не может мой запрос обсчитать...да наплюйте Вы на эти join-ы! Это все чтоб мозги запудрить придумано.

А это "s.coursefk = c.courseid and s.subjectid = cs.subjectfk" по вашему мозгопудрилка? А я, видимо по своей природной глупости, считаю это неявными джойнами...

сделал таблицы, загнал данные
выполнил запрос
select cs.clientfk, count(*)
from courses c, Subjects s, Clients2Subjects cs
where s.coursefk = c.courseid
and s.subjectid = cs.subjectfk
and c.coursestartdate <= 1136062799
and c.courseenddate >= 1133384400
and C.DIRDEPARTMENTFK=2
group by cs.clientfk
запрос вернул 292 строки - в чем проблемы-то?
первичные ключи делал INTEGER, внешние вообще не создавал, ибо не суть пока данные не меняются
выполнил запрос
select cs.clientfk, count(*)
from courses c, Subjects s, Clients2Subjects cs
where s.coursefk = c.courseid
and s.subjectid = cs.subjectfk
and c.coursestartdate <= 1136062799
and c.courseenddate >= 1133384400
and C.DIRDEPARTMENTFK=2
group by cs.clientfk
запрос вернул 292 строки - в чем проблемы-то?
первичные ключи делал INTEGER, внешние вообще не создавал, ибо не суть пока данные не меняются
в данном случае они и есть неявные JOINА это "s.coursefk = c.courseid and s.subjectid = cs.subjectfk" по вашему мозгопудрилка? А я, видимо по своей природной глупости, считаю это неявными джойнами...
и чего ругаться? видимо результаты разные, поскольку данные разные или проблема все же в объявлении полей
преклоняюсь перед Вашими глубокими познаниями в сиквел-таинствах, ув.Гуру. И пардон за стыренные строки из Вашего запроса в моем предыдущем посте, больше не буду.Ivan_Pisarevsky писал(а):Еще, блин, один ламер объявилсяда наплюйте Вы на эти join-ы! Это все чтоб мозги запудрить придумано.
Мусье телепат? На самом деле в этом случае, у меня-ламера, выходов гораздо больше двух: могу выгрузить все на клиента и посчитать перебором, могу пробежаться по тэтэйблам, а еще, а еще селект фром селект забабахаю. Вот.Ivan_Pisarevsky писал(а):который сольет все в универсальное отношение, чтоб без джойнов и будет везде потом вопить какой файрберд тормознутый и глючный не может мой запрос обсчитать...![]()
2stix-s, Вам на ваших данных должно быть гораздо виднее, почему запросы возвращают разные наборы. Пронализируйте результаты своего запроса и запроса без подзапросов с каунт(дистинкт по фк) по конкретному фк, где эти данные разнятся. Может чего и прояснится.
-
- Заслуженный разработчик
- Сообщения: 644
- Зарегистрирован: 15 фев 2005, 11:34
В силу того, что я их выложил в публичном форуме и на всеобщее обозрение можете пользоваться сколько душе угодно компилировать-декомпилировать, извлекать коммерческую выгоду и тд и тп.И пардон за стыренные строки из Вашего запроса в моем предыдущем посте, больше не буду.
Месье знает толк в извращениях. С одинэсом знакомы не понаслышкеНа самом деле в этом случае, у меня-ламера, выходов гораздо больше двух: могу выгрузить все на клиента и посчитать перебором, могу пробежаться по тэтэйблам, а еще, а еще селект фром селект забабахаю. Вот.

ОК, признаю, был груб, сорри.
данные и структура базы не мои, все взято с форума, а вот сложный запросВам на ваших данных должно быть гораздо виднее, почему запросы возвращают разные наборы. Пронализируйте результаты своего запроса и запроса без подзапросов с каунт(дистинкт по фк) по конкретному фк, где эти данные разнятся. Может чего и прояснится.
ORDER BY C.GROUPNUMBER у меня в сумме по COUNT возвращает как раз 293SELECT
C.COURSEID, C.GROUPNUMBER,
(SELECT COUNT(DISTINCT(CS.CLIENTFK)) FROM CLIENTS2SUBJECTS CS
WHERE
CS.SUBJECTFK IN (SELECT SUBJECTID FROM SUBJECTS WHERE COURSEFK=C.COURSEID)
) AS "COUNT"
FROM
COURSES C
WHERE
(SELECT COUNT(*) FROM SUBJECTS WHERE COURSEFK=C.COURSEID)>0 AND
(( 1133384400 BETWEEN C.COURSESTARTDATE AND C.COURSEENDDATE ) OR
( 1136062799 BETWEEN C.COURSESTARTDATE AND C.COURSEENDDATE )) AND
C.DIRDEPARTMENTFK=2

разница тут
COURSEID GROUPNUMBER COUNT
108 47 26(25)
хотелось бы узнать, что получится у автора при выполнении этих запросовselect c.courseid,C.GROUPNUMBER, COUNT(DISTINCT(CS.clientfk))
from courses c, Subjects s, Clients2Subjects cs
where s.coursefk = c.courseid and
s.subjectid = cs.subjectfk and
(( 1133384400 BETWEEN C.COURSESTARTDATE AND C.COURSEENDDATE ) OR
( 1136062799 BETWEEN C.COURSESTARTDATE AND C.COURSEENDDATE )) and
C.DIRDEPARTMENTFK=2
group by c.courseid,C.GROUPNUMBER
order by 3
у меня результаты абсолютно одинаковые

Последний раз редактировалось stix-s 13 дек 2005, 15:54, всего редактировалось 7 раз.
О, да! Только вот никак для себя не решу, кто я в этом виртуальном явлении: мусью или мэдам...Ivan_Pisarevsky писал(а):Месье знает толк в извращениях.Вот.
йес, в самую точку! Но как Вы догадались?!!!Ivan_Pisarevsky писал(а):С одинэсом знакомы не понаслышке![]()
Иван, Вы слишком серьезны!Ivan_Pisarevsky писал(а):ОК, признаю, был груб, сорри.

-
- Заслуженный разработчик
- Сообщения: 644
- Зарегистрирован: 15 фев 2005, 11:34