Суммирование из нескольких таблиц

sukhof
Дата: 28.01.2013 09:07:16
Добрый день! Пожалуйста помогите решить проблемку.

есть три таблицы, первая договора(ca):
caIdcaNomer
11/001
21/002
32/001


вторая таблица предметы договора caPredmet:
caPredmetId idCa caPredmetSum caPredmetName
11100
21200
31300
41500
52100


и третья таблица содержит счета по каждому предмету договора caPay:
caPayId idCaPredmet idCa payOrder caPaySum
111 счет30
211 счет10
311 счет40
421 фактура 200
531 акт 300


Счет на оплату идет за предметом договора, так нужно для экономистов и их отчетов

Мне надо получить список договоров, сумму их предметов, и сумму оплаты по договору.
я делаю следующий запрос:
select caId, idProvider, inn, caNomer, caDate, caDateDone, caSigned, sum(caPredmetSum) from caPredmet
left join ca on ca.caId=caEcoPredmet.id_ca
left join sprovider on sprovider.provider_id=ca.idProvider

group by caPredmet.idCa

в результате получаю правильный список договоров с суммами по предметам. Но стоит мне добавить left join caPay on caPay.idCa=caPredmet.caId и в список полей - sum(caPaySum) то все суммы предметов увеличиваются во столько раз сколько записей в таблице caPay - оно и понятно от чего это происходит. Но как этого избежать не могу врубится ни как. Пожалуйста подскажите что не так делаю.
bochkov
Дата: 28.01.2013 09:18:41
idProvider-?
caEcoPredmet.id_ca-?
sprovider -?
ca.idProvider-?
вы показали не все таблицы и не все столбцы,
покажите SHOW CREATE TABLE скрипт для каждой таблицы, данные не нужны
и запрос где дублируются записи
sukhof
Дата: 28.01.2013 09:29:55
Прошу прощения не заметил простых ошибок, там запрос очень большой с выборкой различных параметров из разных таблиц, пытался сократить ...

таблица по оплате
CREATE TABLE `pay` (
  `payId` int(10) NOT NULL auto_increment,
  `idCa` int(10) default NULL,
  `idCaEcoPredmet` int(10) default NULL,
  `payDocNomer` varchar(25) default NULL,
  `payDocData` date default NULL,
  `payDataKassa` date default NULL,
  `payKassaOrder` varchar(45) default NULL,
  `paySumma` decimal(10,2) default NULL,
  PRIMARY KEY  (`payId`)
) ENGINE=InnoDB AUTO_INCREMENT=256 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT


таблица предметов договоров (eco - экономические предметы в соответствии с фз)
CREATE TABLE `caEcoPredmet` (
  `caEcoPredmetId` int(10) NOT NULL auto_increment,
  `idCa` int(10) default NULL,
  `caEcoPredmetName` varchar(150) default NULL,
  `caEcoPredmetCost` double(10,2) default NULL,
  `caEcoPredmetNum` mediumint(8) default NULL,
  `caEcoPredmetSum` decimal(10,2) default NULL,
  `idNomenkGroup` int(10) default NULL,
  `idOkdp` int(10) default NULL,
  `idPlanArticle` smallint(3) default NULL,
  `idPlanSource` smallint(3) default NULL,
  `idСaTypeEco` smallint(3) default NULL,
  PRIMARY KEY  (`caEcoPredmetId`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8


таблица договоров
CREATE TABLE `ca` (
  `caId` int(10) NOT NULL auto_increment,
  `idProvider` smallint(6) default NULL,
  `idCaType` smallint(2) default NULL,
  `caNomer` varchar(10) default NULL,
  `caDate` date default NULL,
  `caDateDone` date default NULL,
  `caSigned` tinyint(1) default '0',
  `caEcoSigned` tinyint(1) default '0',
  `idCaEcoType` smallint(3) default NULL,
  `idCaTypeZakup` smallint(2) default NULL,
  `caPrim` varchar(255) default NULL,
  `idCaPayRule` smallint(3) default NULL,
  PRIMARY KEY  (`ca_id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8


мне нужно увидеть вот что: caId, sum(caEcoPredmetSum), sum(paySumma)
учитывая что по каждому предмету может быть много счетов, и по договору много предметов ...
Добрый Э - Эх
Дата: 28.01.2013 09:47:26
соединяй не с исходной таблицей платежей, а с её агрегированным представлением:
select caId, idProvider, inn, caNomer, caDate, caDateDone, caSigned, sum(caPredmetSum) from caPredmet
left join ca on ca.caId=caEcoPredmet.id_ca
left join sprovider on sprovider.provider_id=ca.idProvider
left join (select ... from pay group by ...) as v_pay on ...
group by caPredmet.idCa
sukhof
Дата: 28.01.2013 09:59:42
Получилось спасибо огромное!!!!
Сделал вот так
select caId, idProvider, inn, caNomer, caDate, caDateDone, caSigned, sum(caEcoPredmetSum), payed.paySum  from caEcoPredmet
left join ca on caId=caEcoPredmet.idCa
left join sprovider on sprovider.providerId=ca.idProvider

left join (select idCa, sum(pay.paySumma) as paySum from pay group by pay.idCa) as payed on payed.idCa=caEcoPredmet.idCa

group by caEcoPredmet.idCa
bochkov
Дата: 28.01.2013 10:06:07
или прямо в строке считайте
select caId, idProvider, inn, caNomer, caDate, caDateDone, caSigned, sum(caPredmetSum) ,
(SELECT sum(paySumma) FROM pay p WHERE p.caId=caPredmet.caId ) as pay
from caPredmet
left join ca on ca.caId=caEcoPredmet.id_ca
left join sprovider on sprovider.provider_id=ca.idProvider
group by caPredmet.idCa

выбирайте что быстрее
MasterZiv
Дата: 28.01.2013 11:01:42
sukhof
... в список полей - sum(caPaySum) то все суммы предметов увеличиваются во столько раз сколько записей в таблице caPay - оно и понятно от чего это происходит. Но как этого избежать не могу врубится ни как. Пожалуйста подскажите что не так делаю.


Никак.
Тебе надо вычислять сумму отдельным подзапросом, корелированным.

Или некоррелированным подзапросом с group by , записанным как derived table (в from).