![]() |
Показаны 22 сообщений на этой странице |
Форум сетевых администраторов (http://netadmin.ws/forum/index.php)
- MySQL (http://netadmin.ws/forum/forumdisplay.php?forumid=40)
-- Помогите с запросом (http://netadmin.ws/forum/showthread.php?threadid=11031)
Помогите с запросом
Есть 4 таблицы:
CREATE TABLE limits (
id bigint(20) NOT NULL auto_increment,
add_date date NOT NULL default '0000-00-00',
structura_kks_id smallint(5) NOT NULL default '0',
structura_rashodov_id tinyint(4) NOT NULL default '0',
year_of_limit smallint(4) default NULL,
to_year double(12,2) default NULL,
kv1 double(12,2) default NULL,
kv2 double(12,2) default NULL,
kv3 double(12,2) default NULL,
kv4 double(12,2) default NULL,
PRIMARY KEY (id),
UNIQUE KEY id (id)
)
CREATE TABLE rashodi (
id bigint(20) NOT NULL auto_increment,
data_rashoda date NOT NULL default '0000-00-00',
structura_rashodov_id tinyint(4) NOT NULL default '0',
structura_kks_id smallint(5) NOT NULL default '0',
quantity smallint(6) NOT NULL default '0',
unit_price float(9,2) NOT NULL default '0.00',
total_price double(12,2) NOT NULL default '0.00',
nds double(12,2) NOT NULL default '0.00',
nalog_stavka tinyint(3) NOT NULL default '0',
total_price_nds double(12,2) NOT NULL default '0.00',
osnovanie bigint(20) NOT NULL default '0',
PRIMARY KEY (id),
UNIQUE KEY id (id)
)
CREATE TABLE structura_kks (
id smallint(5) NOT NULL auto_increment,
title tinytext NOT NULL,
cleft mediumint(9) NOT NULL default '0',
cright mediumint(9) NOT NULL default '0',
level tinyint(2) NOT NULL default '0',
name tinytext,
info tinytext,
PRIMARY KEY (id),
UNIQUE KEY id (id)
)
CREATE TABLE structura_rashodov (
id tinyint(4) NOT NULL auto_increment,
statia tinytext,
title tinytext NOT NULL,
cleft smallint(6) default NULL,
cright smallint(6) default NULL,
level tinyint(2) default NULL,
info tinytext,
ye tinytext,
PRIMARY KEY (id),
UNIQUE KEY id (id)
)

__________________
Админ - вождь Апачей...
SELECT structura_kks.title AS title, SUM(limits.to_year) AS limits_summ,
SUM(rashodi.total_price_nds) AS rashodi_summ
FROM structura_kks AS structura_kks, limits AS limits, rashodi AS rashodi
WHERE (`rashodi`.`structura_kks_id` >= `structura_kks`.`cleft`) AND
(`rashodi`.`structura_kks_id` <= `structura_kks`.`cright`)
GROUP BY `structura_kks`.`title`
ORDER BY `structura_kks`.`cleft
У меня работает такая конструкция.
__________________
Всего хорошего.
Xel'[Naga] а у меня чего то нет... 
Дело в том, что по определенному стр. подразделению лимиты могут стоять, а доходов не быть или наоборот... Тогда он не выдает его...
__________________
Админ - вождь Апачей...
Ну тогда всё правильно, что не выдаёт.
Вообщем используй 2 запроса, они не такие и большие, чтобы их объединять =)
__________________
Всего хорошего.
Дело в том, что что то в этих запросах не так... :/
Сафсем не так... Посмотрите плз их ещё разок... Не оттаклкиваясь от моих. Т.к. всё ж не то они считают...
Я накосячил ещё в "limits.structura_kks_id >= structura_kks.cleft" ибо это совсем е одно и тоже... (вы с phpDBTree или DB_NestedSet не работали?)
he][es добавил 13-09-2005 в 10:25:36:
Как по идее надо:
Идём по таблице "structura_kks" берем корень дерева. суммируем все из лимитов и расходов что лежит ниже.
идём дальше спускаемся до сл. "ветки" суммируем... и т.д.
КАк это в мин. ое кол-во запросов реализовать ума не приложу...
(на phpclub.ru в статьях оч. хорошо описан принцип функционирования NestedSet)
Сейчас у меня так:
Выбираем из таблицы structura_kks все интересующие нас записи (см. по уровню объектов, к примеру детализация до level=1, ветки 1 и 2ого уровня), потом в цикле (Ð_НÐ_) отправляю запрос к БД Вида:
$q = "SELECT SUM(rashodi.total_price_nds) AS summa_rashodov FROM rashodi INNER JOIN structura_rashodov ON (rashodi.structura_rashodov_id = structura_rashodov.id) INNER JOIN structura_kks ON (rashodi.structura_kks_id = structura_kks.id) WHERE (structura_kks.cleft >= '".$str_kks['cleft']."') AND (structura_kks.cright <= '".$str_kks['cright']."') AND (structura_rashodov.cleft >= '".$str_rashodov['cleft']."') AND (structura_rashodov.cright <= '".$str_rashodov['cright']."')";
//и
$q = "SELECT SUM(limits.to_year) AS summa_limitov FROM limits INNER JOIN structura_kks ON (limits.structura_kks_id = structura_kks.id) INNER JOIN structura_rashodov ON (limits.structura_rashodov_id = structura_rashodov.id) WHERE (structura_kks.cleft >= '".$str_kks['cleft']."') AND (structura_kks.cright <= '".$str_kks['cright']."') AND (structura_rashodov.cleft >= '".$str_rashodov['cleft']."') AND (structura_rashodov.cright <= '".$str_rashodov['cright']."')";

__________________
Админ - вождь Апачей...
Я тебе с радостью помогу, если:
Ты опишешь мне полностью всю струкруту всех таблиц, что означает каждый елемент, и за что он отвечает. В этом роде вообщем. (мне просто тяжело разобраться в твоей структуре 
Ты кинешь кусок твоей рабочей БД, КОТОÐ_ЫЙ точно должен работать(т.е. все условия там должны быть выполнены).
ты опишешь ЧТО КОНКÐ_ЕТНО ТЕБЕ НАДО, только не так, что только ты понимаешь о чём речь.
Я просто, если честно, нифига не понял из твоего первого сообщения. Желательно побольше информации.
И ещё, знать бы, какие идентификаторы у разных отделов, услуг и всего прочего. Вот тогда и можно начать думать.
PS: phpDBTree или DB_NestedSet это случайно не классы для работы с бд?
__________________
Всего хорошего.
ОК. Попытаюсь понятнее... (блин, не могу из MS SQL dump вытрясти, что б сюда приложить...
структуру выдает, а инфу нет... может ещё и с этим подскажете?..)
Посмотрите эту статью: http://phpclub.ru/detail/article/db_tree
У меня есть 2 таких дерева structura_kks и structura_rashodov. Мне необходимо обходя дерево structura_kks брать из таблиц limits и rashodi поля to_year и total_price_nds соответственно складывать их для нижестоящих структурных единиц относительно текущего подразделения.
В аттаче structura_kks и structura_rashodov.
Итак на примере:
Берем "Территориальный орган Федеральной службы государственной статистики по Алтайскому краю", id 1 в тбл. structura_kks. Все остальные стр. подразделеня для него подчиненные, значит склавдываем абсолютно все лимиты и расходы. Идём дальше: берем "Отделы", id = 8, у него есть сл. подчиненные стр.подразделения:
9, Отдел сводной информации и баз данных
10, Отдел населения и демографической статистики
11, Отдел социальной статистики
12, Отдел статистики предприятий и региональных счетов
13, Отдел статистики торговли
14, Отдел статистики финансов
...
23, Финансово-экономический отдел
24, Производственно-технологический отдел
следовательно что бы посчитать лимиты и расходы "Отделов" необходимо сложить строки из табл. limits и rashodi где structura_kks_id = от 8 до 24 (необязательно что эти id идут по порядку!) Воооот... Теперь более понятно объяснил?..
(Заранее очень признателен за помощь!)
__________________
Админ - вождь Апачей...
Всё ясно. Ничего у меня не получается сообразить 
__________________
Всего хорошего.
Во во
Только цикл... Но тогда пол-ся 2хКОЛ-ВО СТр. единиц в базе, запросов.. а это плохо!.. 
__________________
Админ - вождь Апачей...
Не парься ты так сильно, сипользуй как запросы как есть. =)
__________________
Всего хорошего.
Дык это ж какая нагрузка на сервер! У меня в одном месте нечто подобное было, и когда я нормально запрос переписал (вместо цикла, один запрос), среднее время рабооты скрипта с 0,18 до 0,7 сек. сократилось!.. И это на ОЧЕНЬ маленькой БД, а она будет ОЧЕНЬ большая... :/
__________________
Админ - вождь Апачей...
0,18 меньше чем 0,7 8)
__________________
Всего хорошего.
ну в смысле 0,18, и 0,07... =)))
__________________
Админ - вождь Апачей...
В моём случае, это была бы незначительная разница.
Для меня например, загрузка проца, что 1, что 10, не играет никакой роли, комп от этого не начинает медленно работать(по крайней мере я этого не замечаю).
Ты просто определись, что тебе нужно.
Если у тебя данные запросы выполняются каждую сек и постоянно(без перерывов), то тогда да, думаю стоит задуматься об ускорении процесса, а если один раз в день, например, для подробного отчёта, то я бы на твоём месте даже и не чесался по этому поводу, пустая трата времени из-за каких-то 0.11 сек, которые ты даже почувствовать не успеешь.
__________________
Всего хорошего.
В том то и дело их будет много и они будут регулярными, а ещё+ объем БД выростет!.. :/ И сколько тогда будет выполняться запрос даже думать не хочу!...
__________________
Админ - вождь Апачей...
Сколько раз скрипт(программа)(целый сбор отчёта) будет выполняться в день и с какой периодичностью?
Индексируй поля, тогда выбор будет очень быстрым. Насколько я вижу у тебя индексации вообще нет, а вот и зря.
__________________
Всего хорошего.
Ну это да... пока нет. Я знаю что зря 
Насколько часто, пока не знаю... Но достаточно. В частности этот скрипт генерит картинку/график, а их может быть неск. на странице...
И вообще к прим. 10 чел.к (их всего будет не так много.) обратились к сайту, и .... началось перелопачивание базы... по 2-3 раза... (я вот подумываю о введении temporary tables дабы одно и тоже по неск. раз не пересчитывать...)
__________________
Админ - вождь Апачей...
Мля. Ну насмешил-то =)
Вот когда реальная работа будет тормозить(например смотреть загруженность в день и сравнивать с предыдущими днями, если нагрузка будет постоянно расти, тогда да) систему, тогда и можно соображать.
Просто я думаю, что тебе не обойтись тут 1 запросом. Но это моё имхо.
__________________
Всего хорошего.
Ну почему же насмешил?.. См. 10 чел.к к примеру выбор по 4м таблицам: одну в цикле перебирают 96 (пока) записей, суммируют отдельно по ещё 2м, и к ним по id привязывают 3ю... Итого?.. 192 запроса на чел-ка... :/ Причём не самых простых... Имхо это не правильно.
Одним знаю не справиться, хотелось бы как можно меньшим кол-вом. А делать опять же ИМХО нужно правильно и с самого начала.
Зы. Чуток меняется формат таблицы, может поможет:
CREATE TABLE `structura_kks_new` (
`id` int(11) NOT NULL auto_increment,
`title` tinytext NOT NULL,
`root_id` int(11) NOT NULL default '0',
`cleft` int(11) NOT NULL default '0',
`cright` int(11) NOT NULL default '0',
`parent` int(11) NOT NULL default '0',
`norder` int(11) NOT NULL default '0',
`level` int(11) NOT NULL default '0',
`name` tinytext,
`info` tinytext,
PRIMARY KEY (`id`),
KEY `root_id` (`root_id`),
KEY `norder` (`norder`),
KEY `cleft` (`cleft`),
KEY `cright` (`cright`),
KEY `level` (`level`),
KEY `SRLR` (`root_id`,`cleft`,`cright`),
KEY `parent` (`parent`)
) TYPE=MyISAM COMMENT='Structura kks'
__________________
Админ - вождь Апачей...
Теперь насчёт запросов. Не нужно приводить кол-во записей, приводи кол-во запросов всего.
Есть ещё такой вариант:
У тебя всего 4 таблицы, ПУСТЬ даже 4 запроса. Ты делаешь запрос загоняешь все данные в память(массив). И всё, делай с массивом что хочешь. база тебе больше не нужна. Назовём это кешем 
В данном случае тебе придётся писать функции для работы с массивами.
Если хочешь быть уверен, чтобы данные были свежие LOCK TABLE тебя спасёт.
Устраивает такой вариант?
__________________
Всего хорошего.
quote:
Итого?.. 192 запроса на чел-ка...
quote:
Ты делаешь запрос загоняешь все данные в память(массив).
__________________
Админ - вождь Апачей...
2000 записей могут быть разные.
У меня 800.000 записей занимают 160мб всего.
Можно в одну запись затолкать пару мегов. От базы всё зависит.
В твоём случае 2.000 это просто ни о чём, т.к. у тебя в основном цифры.
__________________
Всего хорошего.
| Формат времени GMT. Текущее время 17:58. | Показаны 22 сообщений на этой странице |
Powered by: vBulletin Version 2.2.4
Copyright © Jelsoft Enterprises Limited 2000, 2001.