Форум сетевых администраторов Страницы (2): [1] 2 »
Показаны 22 сообщений на этой странице

Форум сетевых администраторов (http://netadmin.ws/forum/index.php)
- MySQL (http://netadmin.ws/forum/forumdisplay.php?forumid=40)
-- Помогите с запросом (http://netadmin.ws/forum/showthread.php?threadid=11031)


Помещено he][es 11-09-2005 в 22:10:

Помогите с запросом

Есть 4 таблицы:

code:

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)
)



2 с данными limits & rashodi и 2 с древовидными структурами.
Для каждого элемента древовидных структур присутствует лимит, и та сумма которую он потратил.
Необходимо как можно в меньшее количество запросов выбрать и просуммировать лимиты и расходы всех структурных подразделений в соответствии со структурой расходов... (надеюсь не слишком сумбурно объяснил?)


Отделы Статья расходов:Заработная плата Сумма:50000
Отделы Статья расходов:Услуги связи Сумма:150000 (складывается из Услуг связи, Сотового тел. и Интернета)
Отдел сводной информации и баз данных Статья расходов:Услуги связи Сумма:80000
Отдел сводной информации и баз данных Статья расходов:Сотовый телефон Сумма:50000
Отдел сводной информации и баз данных Статья расходов:Интернет Сумма:30000
Отдел социальной статистики Статья расходов:Заработная плата Сумма:50000
Отдел социальной статистики Статья расходов:Услуги связи Сумма:20000
Отдел статистики торговли Статья расходов:Услуги связи Сумма:50000

Причём "глубину" ухода по обоим деревьям нужно регулировать. Те. что бы уровень агригирования задавался. (в нашем случае Сот.тел. и Интернет являются подстатьями для Услуг связи).

Сделал 2 таких запроса:
SELECT
`structura_kks`.`title`,
SUM(`limits`.`to_year`) AS `limits_summ`
FROM
`structura_kks`,
`limits`
WHERE
(`limits`.`structura_kks_id` >= `structura_kks`.`cleft`) AND
(`limits`.`structura_kks_id` <= `structura_kks`.`cright`)
GROUP BY
`structura_kks`.`title`
ORDER BY
`structura_kks`.`cleft`

SELECT
`structura_kks`.`title`,
SUM(`rashodi`.`total_price_nds`) AS `rashodi_summ`
FROM
`structura_kks`,
`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] 12-09-2005 в 03:36:

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

У меня работает такая конструкция.

__________________
Всего хорошего.


Помещено he][es 12-09-2005 в 05:01:

Xel'[Naga] а у меня чего то нет...
Дело в том, что по определенному стр. подразделению лимиты могут стоять, а доходов не быть или наоборот... Тогда он не выдает его...

__________________
Админ - вождь Апачей...


Помещено Xel'[Naga] 12-09-2005 в 17:37:

Ну тогда всё правильно, что не выдаёт.
Вообщем используй 2 запроса, они не такие и большие, чтобы их объединять =)

__________________
Всего хорошего.


Помещено he][es 13-09-2005 в 10:12:

Дело в том, что что то в этих запросах не так... :/
Сафсем не так... Посмотрите плз их ещё разок... Не оттаклкиваясь от моих. Т.к. всё ж не то они считают...
Я накосячил ещё в "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ого уровня), потом в цикле (Ð_НÐ_) отправляю запрос к БД Вида:

PHP:


$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']."')";


Где $str_kks['cright'], $str_kks['cleft'], $str_rashodov['cleft'] и $str_rashodov['cright'] - это ограничения по дереву (т.е. только та ветка которая нас интересует).
Те. получается Огромная куча запросов (около 200).. И работает это соответственно.

__________________
Админ - вождь Апачей...


Помещено Xel'[Naga] 13-09-2005 в 12:49:

Я тебе с радостью помогу, если:
Ты опишешь мне полностью всю струкруту всех таблиц, что означает каждый елемент, и за что он отвечает. В этом роде вообщем. (мне просто тяжело разобраться в твоей структуре
Ты кинешь кусок твоей рабочей БД, КОТОÐ_ЫЙ точно должен работать(т.е. все условия там должны быть выполнены).
ты опишешь ЧТО КОНКÐ_ЕТНО ТЕБЕ НАДО, только не так, что только ты понимаешь о чём речь.

Я просто, если честно, нифига не понял из твоего первого сообщения. Желательно побольше информации.
И ещё, знать бы, какие идентификаторы у разных отделов, услуг и всего прочего. Вот тогда и можно начать думать.

PS: phpDBTree или DB_NestedSet это случайно не классы для работы с бд?

__________________
Всего хорошего.


Помещено he][es 14-09-2005 в 16:34:

ОК. Попытаюсь понятнее... (блин, не могу из 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 идут по порядку!) Воооот... Теперь более понятно объяснил?..
(Заранее очень признателен за помощь!)

__________________
Админ - вождь Апачей...


Помещено Xel'[Naga] 15-09-2005 в 01:23:

Всё ясно. Ничего у меня не получается сообразить

__________________
Всего хорошего.


Помещено he][es 15-09-2005 в 08:53:

Во во Только цикл... Но тогда пол-ся 2хКОЛ-ВО СТр. единиц в базе, запросов.. а это плохо!..

__________________
Админ - вождь Апачей...


Помещено Xel'[Naga] 15-09-2005 в 09:29:

Не парься ты так сильно, сипользуй как запросы как есть. =)

__________________
Всего хорошего.


Помещено he][es 15-09-2005 в 12:28:

Дык это ж какая нагрузка на сервер! У меня в одном месте нечто подобное было, и когда я нормально запрос переписал (вместо цикла, один запрос), среднее время рабооты скрипта с 0,18 до 0,7 сек. сократилось!.. И это на ОЧЕНЬ маленькой БД, а она будет ОЧЕНЬ большая... :/

__________________
Админ - вождь Апачей...


Помещено Xel'[Naga] 15-09-2005 в 21:20:

0,18 меньше чем 0,7 8)

__________________
Всего хорошего.


Помещено he][es 16-09-2005 в 07:44:

ну в смысле 0,18, и 0,07... =)))

__________________
Админ - вождь Апачей...


Помещено Xel'[Naga] 16-09-2005 в 08:00:

В моём случае, это была бы незначительная разница.
Для меня например, загрузка проца, что 1, что 10, не играет никакой роли, комп от этого не начинает медленно работать(по крайней мере я этого не замечаю).
Ты просто определись, что тебе нужно.
Если у тебя данные запросы выполняются каждую сек и постоянно(без перерывов), то тогда да, думаю стоит задуматься об ускорении процесса, а если один раз в день, например, для подробного отчёта, то я бы на твоём месте даже и не чесался по этому поводу, пустая трата времени из-за каких-то 0.11 сек, которые ты даже почувствовать не успеешь.

__________________
Всего хорошего.


Помещено he][es 16-09-2005 в 09:15:

В том то и дело их будет много и они будут регулярными, а ещё+ объем БД выростет!.. :/ И сколько тогда будет выполняться запрос даже думать не хочу!...

__________________
Админ - вождь Апачей...


Формат времени GMT. Текущее время 14:03. Страницы (2): [1] 2 »
Показаны 22 сообщений на этой странице

Powered by: vBulletin Version 2.2.4
Copyright © Jelsoft Enterprises Limited 2000, 2001.