我这里有一个主表:
BillCode CoutName Type data
0100001 公司1 收货 2009-03-20
0100002 公司1 退货 2009-03-22
0100003 公司2 收货 2009-03-22
从表
BillCode Number
0100001 24
0100001 523
0100001 41
0100002 582
0100002 41
0100003 54
现在我需要汇总主从表的数据,格式如下
CoutName InNumber(入库) OutNumber(入库)
公司1 588 992
公司2 54
意思就是,汇总每个公司出货的总数量,退货的总数量,其中数量就是一个简单的加总。我自己写了N个SQL,但是可以分组,却没有数量显示出来:
procedure TfrmCgGysHz.rzbtbtnViewClick(Sender: TObject);
var
SQLStr : string;
begin
gsDrawDBGridEhTitle(frmDM.qryAll, dbgrdhCgGysHz, 'CgGysHz', frmDM.dsRptCenter);
{
SQLStr := 'Select A.CoutName,Sum(B.TNumber) As TNumber From T_Bill A '+
'Left Join T_BillDetail B On A.BillCode=B.BillCode Group By A.CoutName';
SQLStr := 'Select A.CoutName,Sum(B.TNumber) As TNumber,'+
'Sum(B.Price*B.TNumber) As TMoney From T_Bill A '+
'Left Join T_BillDetail B On A.BillCode=B.BillCode '+
'where A.Identifier = '+''''+'采购收货'+''''+ ' '+
'and addDate between :StartDate and :EndDate '+
'Group By A.CoutName';
}
{ SQLStr := 'Select '+
'A.CoutName,'+
'Sum(C.TNumber) As TInNumber,'+
'Sum(C.Price*C.TNumber) As TInMoney,'+
'C.TOutNumber,C.TOutMoney '+
'From '+
'T_Bill A '+
'Left Join ('+
'select '+
'A.CoutName,'+
'B.Price,'+
'B.TNumber,'+
'Sum(B.TNumber) As TOutNumber,'+
'Sum(B.Price*B.TNumber) As TOutMoney '+
'From '+
'T_Bill A '+
'Left Join T_BillDetail B '+
'On '+
'A.BillCode=B.BillCode '+
'where '+
'A.Identifier = '+''''+'采购退货'+''''+' '+
'and '+
'addDate between :StartDate and :EndDate '+
'Group By A.CoutName) C On A.CoutName=C.CoutName '+
'where A.Identifier = '+''''+'采购收货'+''''+ ' '+
'and addDate between :StartDate and :EndDate '+
'Group By A.CoutName'; }
{ SQLStr := 'Select A.CoutName,Sum(C.TNumber) As TInNumber,'+
'Sum(C.Price*C.TNumber) As TInMoney,C.TOutNumber,C.TOutMoney From T_Bill A '+
'Left Join (select A.BillCode As BillCode,A.CoutName,B.Price,B.TNumber,Sum(B.TNumber) As TOutNumber,Sum(B.Price*B.TNumber) As TOutMoney From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode where A.Identifier = '+''''+'采购退货'+''''+' Group By A.CoutName) C On A.BillCode=C.BillCode '+
'where A.Identifier = '+''''+'采购收货'+''''+ ' '+
'and addDate between :StartDate and :EndDate '+
'Group By A.CoutName';}
{ SQLStr := 'Select A.CoutName,(Select Sum(B.TNumber) As TInNumber From T_Bill A,T_BillDetail B Where A.BillCode = '+
'B.BillCode Group By A.CoutName) As TInNumber '+
'From T_Bill A,T_BillDetail B ';
//'Where addDate between :StartDate and :EndDate '+
//'Group By A.CoutName'; }
SQLStr := 'Select A.CoutName,Sum(C.TNumber) As TInNumber,'+
'Sum(C.Price*C.TNumber) As TInMoney,C.TOutNumber,C.TOutMoney From T_Bill A '+
'Left Join (select B.BillCode,B.Price,B.TNumber,B.Price As OutPrice,B.TNumber As TOutNumber From T_BillDetail where A.BillCode=B.BillCode) C On A.BillCode=C.BillCode '+
'where A.Identifier = '+''''+'采购收货'+''''+ ' '+
'and addDate between :StartDate and :EndDate '+
'Group By A.CoutName';
with frmDM.qryTmp do
begin
Close;
SQL.Clear;
SQL.Add(SQLStr);
Parameters.ParamByName('StartDate').Value:=edtBegin.Value;
Parameters.ParamByName('EndDate').Value:=edtEnd.Value;
Open;
end;
end;
汇总的效果就是这样的
42 个解决方案
#1
好长
#2
绿色部分是我取消了的失败代码,下面的才是最接近的。
#3
InNumber,OutNumber怎么获得啊 ?
#4
select temp1.CoutName,temp1.sum(Number),temp2.sum(Number)
from (select CoutName,sum(Number) from a,c where a.BillCode=c.BillCode and Type='收货' group by CoutName) temp1,(select CoutName,sum(Number) from a,c where a.BillCode=c.BillCode and Type='退货' group by CoutName) temp2
where temp1.CoutName=temp2.CoutName
#5
TO:lgx0914
InNumber,OutNumber这些是虚拟的字段,都是油从表的INumber派生出来的。
InNumber,OutNumber这些是虚拟的字段,都是油从表的INumber派生出来的。
#6
select a.CoutName,b.InNumber, c.OutNumber from 主表 left join
(select CoutName,sum(Number) as InNumber from 从表 group by CoutName) b on b.CoutName=a.CoutName
left join (select CoutName,sum(Number) as OutNumbe from 从表 group by CoutName) b on a.CoutName=a.CoutName
(select CoutName,sum(Number) as InNumber from 从表 group by CoutName) b on b.CoutName=a.CoutName
left join (select CoutName,sum(Number) as OutNumbe from 从表 group by CoutName) b on a.CoutName=a.CoutName
#7
select a.CoutName ,
sum(case when a.Type='收货' then b.Number else 0 end) as InNumber,
sum(case when a.Type='退货' then b.Number else 0 end) as OutNumber
from T_Bill a,T_BillDetail b
where a.BillCode=b.BillCode
--其他日期条件等自己加
group by a.CoutName
#8
没测试过代码
#9
2.0版
select temp1.CoutName,temp1.InNumber,temp2.OutNumber
from (select CoutName,sum(Number) InNumber from a,c where a.BillCode=c.BillCode and Type='收货' group by CoutName) temp1
full join (select CoutName,sum(Number) OutNumber from a,c where a.BillCode=c.BillCode and Type='退货' group by CoutName) temp2
on temp1.CoutName=temp2.CoutName
#10
TO:lhylhy
经过变形,结合我的实际应该是这样的语句,但是老是提示“未指定的错误”
经过变形,结合我的实际应该是这样的语句,但是老是提示“未指定的错误”
SQLStr := 'select temp1.CoutName As coutname,temp1.TInNumber as TInNumber,temp2.TOutNumber as TOutNumber'+
'from (select a.CoutName As CoutName,sum(c.TNumber) As TInNumber from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.Identifier='+'''采购收货'''+' group by a.CoutName) temp1 '+
'full join (select a.CoutName As CoutName,sum(c.TNumber) As TOutNumber from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.Identifier='+'''采购退货'''+' group by a.CoutName) temp2 '+
'on temp1.CoutName=temp2.CoutName ';
#11
TO:ron_xin,同样是“未指定的错误”
SQLStr := 'select a.CoutName ,'+
'sum(case when a.Identifier='+''''+'采购收货'+''''+' then b.TNumber else 0 end) as TInNumber,'+
'sum(case when a.Identifier='+''''+'采购退货'+''''+' then b.TNumber else 0 end) as TOutNumber '+
'from T_Bill a,T_BillDetail b '+
'where a.BillCode=b.BillCode '+
//--其他日期条件等自己加
'group by a.CoutName ';
#12
汗,从第一句,转成现在这么一句强!
=================================
看不出错来.:> 算路过.
=================================
看不出错来.:> 算路过.
#13
有的数据库好像不用as,至少在某些地方不用,你用的是什么数据库?
#14
我用的是access,as是支持的,我在最简单的SQL语句中试过:
上面的语句就运行得很好,就是不能多插入另外两列,让用户知道退货的情况。
SQLStr := 'Select A.CoutName,Sum(B.TNumber) As TNumber,'+
'Sum(B.Price*B.TNumber) As TMoney From T_Bill A '+
'Left Join T_BillDetail B On A.BillCode=B.BillCode '+
'where A.Identifier = '+''''+'采购收货'+''''+ ' '+
'and addDate between :StartDate and :EndDate '+
'Group By A.CoutName';
上面的语句就运行得很好,就是不能多插入另外两列,让用户知道退货的情况。
#15
SQLStr := 'Select A.CoutName,Sum(B.TNumber) As TNumber,Sum(B.Price*B.TNumber) As TMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName';
如果这一句能行的话,那你就这样的吧
SQLStr := '(Select A.CoutName,Sum(B.TNumber) As TNumber,Sum(B.Price*B.TNumber) As TMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)';
SQLStr:= ' union '
SQLStr := '(Select A.CoutName,Sum(B.TNumber) As TNumber,Sum(B.Price*B.TNumber) As TMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购退货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)';
把二表连起来....不过.这种效率比较低.能用SELECT语句尽量用一句.
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName';
如果这一句能行的话,那你就这样的吧
SQLStr := '(Select A.CoutName,Sum(B.TNumber) As TNumber,Sum(B.Price*B.TNumber) As TMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)';
SQLStr:= ' union '
SQLStr := '(Select A.CoutName,Sum(B.TNumber) As TNumber,Sum(B.Price*B.TNumber) As TMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购退货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)';
把二表连起来....不过.这种效率比较低.能用SELECT语句尽量用一句.
#16
SQLStr := '(Select A.CoutName,Sum(B.TNumber) As TOutNumber,Sum(B.Price*B.TNumber) As TOutMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购退货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)';
SQLStr:= SQLStr +' union ' ;
SQLStr := SQLStr + '(Select A.CoutName,Sum(B.TNumber) As TInNumber,Sum(B.Price*B.TNumber) As TInMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)';
这个语句,只能计算前面的部分,后门的收货也是显示不出来,反之,为止掉乱一下也是一样的。
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购退货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)';
SQLStr:= SQLStr +' union ' ;
SQLStr := SQLStr + '(Select A.CoutName,Sum(B.TNumber) As TInNumber,Sum(B.Price*B.TNumber) As TInMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)';
这个语句,只能计算前面的部分,后门的收货也是显示不出来,反之,为止掉乱一下也是一样的。
#17
呵呵,没有数据表,只能猜着做.
================================
SQLStr := 'select * form ( (Select A.CoutName,Sum(B.TNumber) As TOutNumber,Sum(B.Price*B.TNumber) As TOutMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购退货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName) ) as a';
SQLStr:= SQLStr +' union ' ;
SQLStr := SQLStr + 'select * from ( (Select A.CoutName,Sum(B.TNumber) As TInNumber,Sum(B.Price*B.TNumber) As TInMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)) as b';
你这样再试试.把二个查询语句的结果变成二张表,然后连起来.得到一张整表.
================================
SQLStr := 'select * form ( (Select A.CoutName,Sum(B.TNumber) As TOutNumber,Sum(B.Price*B.TNumber) As TOutMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购退货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName) ) as a';
SQLStr:= SQLStr +' union ' ;
SQLStr := SQLStr + 'select * from ( (Select A.CoutName,Sum(B.TNumber) As TInNumber,Sum(B.Price*B.TNumber) As TInMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)) as b';
你这样再试试.把二个查询语句的结果变成二张表,然后连起来.得到一张整表.
#18
TO:nbzip
错误提示:不正常地定义参数对象。提供了不一致或不完整的信息。
其实这个问题,如果使用一个物理的临时表,做起来是很简单的,只要把两次的查询结果插入到物理临时表中,然后再Group By一次,但是我现在希望这些数据都存放在内存中。我使用了TADOQuery作为TDataSource的dataset,而不是TADOTable作为dataset。我希望达到的效果是,精简数据库的结构,尽量放弃使用物理表作为临时表,因为如果查询的显示形式越多,需要的物理临时表就愈多,这个我希望尽量避免。
错误提示:不正常地定义参数对象。提供了不一致或不完整的信息。
其实这个问题,如果使用一个物理的临时表,做起来是很简单的,只要把两次的查询结果插入到物理临时表中,然后再Group By一次,但是我现在希望这些数据都存放在内存中。我使用了TADOQuery作为TDataSource的dataset,而不是TADOTable作为dataset。我希望达到的效果是,精简数据库的结构,尽量放弃使用物理表作为临时表,因为如果查询的显示形式越多,需要的物理临时表就愈多,这个我希望尽量避免。
#19
SQLStr := 'select a.CoutName ,'+
'sum(case when a.Identifier='+''''+'采购收货'+''''+' then b.TNumber else 0 end) as TInNumber,'+
'sum(case when a.Identifier='+''''+'采购退货'+''''+' then b.TNumber else 0 end) as TOutNumber '+
'from T_Bill a,T_BillDetail b '+
'where a.BillCode=b.BillCode '+
//--其他日期条件等自己加
'group by a.CoutName ';
============================================跟据上面这句,我用自己的表,试了一下,没什么问题啊.
SELECT dept,sum(CASE WHEN ind=1 THEN p_qty ELSE 0 END) AS q1,sum(CASE WHEN ind=8 THEN p_qty ELSE 0 END) AS q2
FROM wh_in WHERE y=2009 GROUP BY dept
只是我的是一张表,你的是二张合在一起的一张表. 你自己再查查哪里写的有问题.噢我用的是MS SQL2005
select * from (select a.countname,a.identifier,b.tnumber from T_Bill a left join T_BillDetail b on a.bill_code=b.bill_code) as a
如果还不行,你把结果集转成一张表,然后再统计一下试试.
'sum(case when a.Identifier='+''''+'采购收货'+''''+' then b.TNumber else 0 end) as TInNumber,'+
'sum(case when a.Identifier='+''''+'采购退货'+''''+' then b.TNumber else 0 end) as TOutNumber '+
'from T_Bill a,T_BillDetail b '+
'where a.BillCode=b.BillCode '+
//--其他日期条件等自己加
'group by a.CoutName ';
============================================跟据上面这句,我用自己的表,试了一下,没什么问题啊.
SELECT dept,sum(CASE WHEN ind=1 THEN p_qty ELSE 0 END) AS q1,sum(CASE WHEN ind=8 THEN p_qty ELSE 0 END) AS q2
FROM wh_in WHERE y=2009 GROUP BY dept
只是我的是一张表,你的是二张合在一起的一张表. 你自己再查查哪里写的有问题.噢我用的是MS SQL2005
select * from (select a.countname,a.identifier,b.tnumber from T_Bill a left join T_BillDetail b on a.bill_code=b.bill_code) as a
如果还不行,你把结果集转成一张表,然后再统计一下试试.
#20
数据源其实是一张表,以单价类别字段来区分业务类型,通过提取方向操作的两个相对应的业务来得出如上图中的结果。
#21
数据源其实是一张表,以单据类别字段来区分业务类型,通过提取反向操作的两个相对应的业务来得出如上图中的结果。
#22
呵呵,我们调试程序,先尽快把答案给得到.只要能得到,就行.不要管如何得到.
然后,下部就是优化程序. 你暂时不要管别人如何得到结果,你只要得到对的结果.然后对这种结果再行优化.
(如果你得不到答案,可能就不能尽入下一步开发.你可以先得到差的答案,然后,再提问,然后你自己做下步,最后,
你得到答案或别人处得到答案,再心量的分析,优化.写入自己程序,然后提交任务.)
然后,下部就是优化程序. 你暂时不要管别人如何得到结果,你只要得到对的结果.然后对这种结果再行优化.
(如果你得不到答案,可能就不能尽入下一步开发.你可以先得到差的答案,然后,再提问,然后你自己做下步,最后,
你得到答案或别人处得到答案,再心量的分析,优化.写入自己程序,然后提交任务.)
#23
我现在也可以讲属于优化阶段了
使用
SQLStr := 'Select A.CoutName,Sum(B.TNumber) As TNumber,Sum(B.Price*B.TNumber) As TMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName';
可以得到一半的结果,
再使用
SQLStr := SQLStr + '(Select A.CoutName,Sum(B.TNumber) As TInNumber,Sum(B.Price*B.TNumber) As TInMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)';
又得到了一半的结果
,再把两个表格Group By A.CoutName 那么就得到了上图的效果了
我现在希望了解能不能不使用临时表的情况下,完成这个事情,这样的话,数据库的表就更少了。
使用
SQLStr := 'Select A.CoutName,Sum(B.TNumber) As TNumber,Sum(B.Price*B.TNumber) As TMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName';
可以得到一半的结果,
再使用
SQLStr := SQLStr + '(Select A.CoutName,Sum(B.TNumber) As TInNumber,Sum(B.Price*B.TNumber) As TInMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)';
又得到了一半的结果
,再把两个表格Group By A.CoutName 那么就得到了上图的效果了
我现在希望了解能不能不使用临时表的情况下,完成这个事情,这样的话,数据库的表就更少了。
#24
TO:nbzip ,很感谢您的忠告,我在实际上,也是这么想这么做的。经过方法不好,但是能达到目的是最要紧的,方法以后可以改进。但是有时候做起程序也很较真,希望懂得更多,也希望尝试不同的方法达到目的。
#25
其他地方用form子查询正常吗?
#26
正常啊,我都没有进行过其他的查询,直接进入那里的。
#27
而且,我使用的是一个独立的TADOQuery,而不是公共TADOQuery,上面已经说明了,只提取一个类型的单据,运行结果是正确的,现在希望分类型提取结果,并显示在一个查询结果里。
#28
我是说像我写的那样,在form子句里有一个子查询的sql,一般子查询都是在where子句,会不会对form子句里的子查询的支持有问题?
#29
很有可能,这就解释了为什么连接两个子表后为什么只能查询出前面部分的内容,而显示不了后面部分。
#30
procedure TfrmCgGysHz.rzbtbtnViewClick(Sender: TObject);
var
SQLStr : string;
begin
//产生dbgrideh的字段
gsDrawDBGridEhTitle(frmDM.qryAll, dbgrdhCgGysHz, 'CgGysHz', frmDM.dsCgGysHz);
with frmDM.qryTmp do
begin
//取消dbgrideh的数据关联
dbgrdhCgGysHz.DataSource := nil;
Close;
SQL.Clear;
SQL.Add('delete * from CgGysHz'); //删除物料临时表的内容
ExecSQL;
//汇总采购收货单价的进货数量和金额
SQLStr := 'Select A.CoutName As CoutName,Sum(B.TNumber) As TInNumber,'+
'Sum(B.Price*B.TNumber) As TInMoney From T_Bill A '+
'Left Join T_BillDetail B On A.BillCode=B.BillCode '+
'where A.Identifier = '+''''+'采购收货'+''''+ ' '+
'and addDate between :StartDate and :EndDate '+
'Group By A.CoutName';
Close;
SQL.Clear;
SQL.Add(SQLStr);
Parameters.ParamByName('StartDate').Value:=edtBegin.Value;
Parameters.ParamByName('EndDate').Value:=edtEnd.Value;
Open;
//把采购收货的数据插入到物料临时表
SQLStr := 'insert into CgGysHz(CoutName,TInNumber,TInMoney) values('+
Quotedstr(FieldByName('CoutName').AsString)+
','+Quotedstr(fieldbyname('TInNumber').AsString)+
','+Quotedstr(fieldbyname('TInMoney').AsString)+')' ;
while not Eof do
begin
with frmDM.qryAll do
begin
Close;
SQL.Clear;
SQL.Add(SQLStr);
ExecSQL;
end;
Next;
end;
//汇总采购退货单据的进货数量和金额
SQLStr := 'Select A.CoutName As CoutName,Sum(B.TNumber) As TOutNumber,'+
'Sum(B.Price*B.TNumber) As TOutMoney From T_Bill A '+
'Left Join T_BillDetail B On A.BillCode=B.BillCode '+
'where A.Identifier = '+''''+'采购退货'+''''+ ' '+
'and addDate between :StartDate and :EndDate '+
'Group By A.CoutName';
Close;
SQL.Clear;
SQL.Add(SQLStr);
Parameters.ParamByName('StartDate').Value:=edtBegin.Value;
Parameters.ParamByName('EndDate').Value:=edtEnd.Value;
Open;
//把采购退货的数据插入到物料临时表
SQLStr := 'insert into CgGysHz(CoutName,TOutNumber,TOutMoney) values('+
Quotedstr(FieldByName('CoutName').AsString)+
','+Quotedstr(fieldbyname('TOutNumber').AsString)+
','+Quotedstr(fieldbyname('TOutMoney').AsString)+')' ;
while not Eof do
begin
with frmDM.qryAll do
begin
Close;
SQL.Clear;
SQL.Add(SQLStr);
ExecSQL;
end;
Next;
end;
//刷新物料临时表的内容
frmDM.tblCgGysHz.Active := False;
frmDM.tblCgGysHz.Active := True;
//汇总进货和退货的数据
SQLStr := 'Select A.CoutName,sum(A.TInNumber) As TInNumber,'+
'sum(A.TInMoney) As TInMoney,sum(A.TOutNumber) As TOutNumber,sum(A.TOutMoney) As TOutMoney '+' From CgGysHz A '+
'Group By A.CoutName';
Close;
SQL.Clear;
SQL.Add(SQLStr);
Open;
//建立dbgrideh的数据关联
dbgrdhCgGysHz.DataSource := frmDM.dsRptCenter;
end;
//刷新dbgrideh的数据
dbgrdhCgGysHz.DataSource.DataSet.Active := False;
dbgrdhCgGysHz.DataSource.DataSet.Active := True;
end;
这个就是使用物料临时表的代码,要达到问题给出的效果,使用物理临时表,不但繁琐,而且效率很低很低!!!
#31
我使用的是Access数据库,大家可能使用MSSQL做的测试,我试了一下
这个语句在MSSQL中就可以得到我要的结果!!晕!为什么在Access中就不行呢!
select
temp1.CoutName,temp1.TInNumber,temp1.TInMoney,temp2.TOutNumber,temp2.TOutMoney
from
(select a.CoutName As CoutName,sum(c.TNumber) As TInNumber,Sum(c.Price*c.TNumber) As TInMoney from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.Identifier='采购收货' group by a.CoutName) temp1
full join
(select a.CoutName As CoutName,sum(c.TNumber) As TOutNumber,Sum(c.Price*c.TNumber) As TOutMoney from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.Identifier='采购退货' group by a.CoutName) temp2
on
temp1.CoutName=temp2.CoutName
这个语句在MSSQL中就可以得到我要的结果!!晕!为什么在Access中就不行呢!
#32
full join 使用正常吗?会不会是access不支持full join?
#33
下面的在MSSQL上也可以执行!狂晕!~~
SQLStr := 'select a.CoutName ,'+
'sum(case when a.Identifier='+''''+'采购收货'+''''+' then b.TNumber else 0 end) as TInNumber,'+
'sum(case when a.Identifier='+''''+'采购退货'+''''+' then b.TNumber else 0 end) as TOutNumber '+
'from T_Bill a,T_BillDetail b '+
'where a.BillCode=b.BillCode '+
'and addDate between :StartDate and :EndDate '+
'group by a.CoutName ';
#34
反正大家给我的语句在MSSQL上好像都有结果,这个恐怕是delphi的Access驱动有问题,也可能是delphi2009 sp4本身的bug。原来听讲它的数据库驱动有bug,我没有碰到过,所以不是很相信,也不以为然,现在看来真有那么一回事!倒!~
#35
这个是完全符合要求的语句,但是只在MSSQL上可用,在ACCESS上提示“示知的错误”!!
SQLStr := 'select a.CoutName ,'+
'sum(case when a.Identifier='+''''+'采购收货'+''''+
' then b.TNumber else 0 end) as TInNumber,'+
'sum(case when a.Identifier='+''''+'采购收货'+''''+
' then b.Price*b.TNumber else 0 end) as TInMoney,'+
'sum(case when a.Identifier='+''''+'采购退货'+''''+
' then b.TNumber else 0 end) as TOutNumber,'+
'sum(case when a.Identifier='+''''+'采购退货'+''''+
' then b.Price*b.TNumber else 0 end) as TOutMoney '+
'from T_Bill a,T_BillDetail b '+
'where a.BillCode=b.BillCode '+
'and addDate between :StartDate and :EndDate '+
'group by a.CoutName ';
with frmDM.qryTmp do
begin
Close;
SQL.Clear;
SQL.Add(SQLStr);
Parameters.ParamByName('StartDate').Value:=edtBegin.Value;
Parameters.ParamByName('EndDate').Value:=edtEnd.Value;
Open;
end;
#36
已查明,access不支持FULL JOIN
#37
(select
temp1.CoutName,temp1.TInNumber,temp1.TInMoney,temp2.TOutNumber,temp2.TOutMoney
from
(select a.CoutName As CoutName,sum(c.TNumber) As TInNumber,Sum(c.Price*c.TNumber) As TInMoney
from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.Identifier='采购收货' group by a.CoutName) temp1
left join
(select a.CoutName As CoutName,sum(c.TNumber) As TOutNumber,Sum(c.Price*c.TNumber) As TOutMoney
from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.Identifier='采购退货' group by a.CoutName) temp2
on
temp1.CoutName=temp2.CoutName)
UNION
(select
temp2.CoutName,temp1.TInNumber,temp1.TInMoney,temp2.TOutNumber,temp2.TOutMoney
from
(select a.CoutName As CoutName,sum(c.TNumber) As TInNumber,Sum(c.Price*c.TNumber) As TInMoney
from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.Identifier='采购收货' group by a.CoutName) temp1
right join
(select a.CoutName As CoutName,sum(c.TNumber) As TOutNumber,Sum(c.Price*c.TNumber) As TOutMoney
from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.Identifier='采购退货' group by a.CoutName) temp2
on
temp1.CoutName=temp2.CoutName)
试一试
#38
TO:lhylhy
这个语句终于可以汇总了,但是不知道怎么添加时间区间的变量?如果SQL语句中使用两次就会报错的。
这个语句终于可以汇总了,但是不知道怎么添加时间区间的变量?如果SQL语句中使用两次就会报错的。
#39
SQLStr := '(select '+
'temp1.CoutName,temp1.TInNumber,temp1.TInMoney,temp2.TOutNumber,temp2.TOutMoney '+
'from '+
'(select a.CoutName As CoutName,sum(c.TNumber) As TInNumber,Sum(c.Price*c.TNumber) As TInMoney '+
'from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.addDate between :StartDate and :EndDate and a.Identifier='+'''采购收货'''+' group by a.CoutName) temp1 '+
'left join '+
'(select a.CoutName As CoutName,sum(c.TNumber) As TOutNumber,Sum(c.Price*c.TNumber) As TOutMoney '+
'from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.addDate between :StartDate and a.Identifier='+'''采购退货'''+' group by a.CoutName) temp2 '+
'on '+
'temp1.CoutName=temp2.CoutName) '+
'UNION '+
'(select '+
'temp2.CoutName,temp1.TInNumber,temp1.TInMoney,temp2.TOutNumber,temp2.TOutMoney '+
'from '+
'(select a.CoutName As CoutName,sum(c.TNumber) As TInNumber,Sum(c.Price*c.TNumber) As TInMoney '+
'from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.addDate between :StartDate and a.Identifier='+'''采购收货'''+' group by a.CoutName) temp1 '+
'right join '+
'(select a.CoutName As CoutName,sum(c.TNumber) As TOutNumber,Sum(c.Price*c.TNumber) As TOutMoney '+
'from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.addDate between :StartDate and a.Identifier='+'''采购退货'''+' group by a.CoutName) temp2 '+
'on '+
'temp1.CoutName=temp2.CoutName) ';
with frmDM.qryTmp do
begin
Close;
SQL.Clear;
SQL.Add(SQLStr);
Parameters.ParamByName('StartDate').Value:=edtBegin.Value;
Parameters.ParamByName('EndDate').Value:=edtEnd.Value;
Open;
end;
加上时间区间,仍然只计算前面的内容。
#40
时间是不是应该都写成这样
(a.addDate between :StartDate and :EndDate)
#41
SQLStr := 'select a.CoutName ,'+
'sum(iif( a.Identifier='+''''+'采购收货'+''''+
' ,b.TNumber , 0 )) as TInNumber,'+
'sum(iif (a.Identifier='+''''+'采购收货'+''''+
' ,b.Price*b.TNumber ,0 )) as TInMoney,'+
'sum(iif ( a.Identifier='+''''+'采购退货'+''''+
' ,b.TNumber ,0 )) as TOutNumber,'+
'sum(iif ( a.Identifier='+''''+'采购退货'+''''+
' ,b.Price*b.TNumber ,0 )) as TOutMoney '+
'from T_Bill a,T_BillDetail b '+
'where a.BillCode=b.BillCode '+
'and addDate between :StartDate and :EndDate '+
'group by a.CoutName ';
在SQL板块,某个高人写的,恐怕这个是答案了。
#42
TO:lhylhy
严格起来可能需要这样,但是我现在只有主表有adddate字段,所以程序仍然正确识别的。
严格起来可能需要这样,但是我现在只有主表有adddate字段,所以程序仍然正确识别的。
#1
好长
#2
绿色部分是我取消了的失败代码,下面的才是最接近的。
#3
InNumber,OutNumber怎么获得啊 ?
#4
select temp1.CoutName,temp1.sum(Number),temp2.sum(Number)
from (select CoutName,sum(Number) from a,c where a.BillCode=c.BillCode and Type='收货' group by CoutName) temp1,(select CoutName,sum(Number) from a,c where a.BillCode=c.BillCode and Type='退货' group by CoutName) temp2
where temp1.CoutName=temp2.CoutName
#5
TO:lgx0914
InNumber,OutNumber这些是虚拟的字段,都是油从表的INumber派生出来的。
InNumber,OutNumber这些是虚拟的字段,都是油从表的INumber派生出来的。
#6
select a.CoutName,b.InNumber, c.OutNumber from 主表 left join
(select CoutName,sum(Number) as InNumber from 从表 group by CoutName) b on b.CoutName=a.CoutName
left join (select CoutName,sum(Number) as OutNumbe from 从表 group by CoutName) b on a.CoutName=a.CoutName
(select CoutName,sum(Number) as InNumber from 从表 group by CoutName) b on b.CoutName=a.CoutName
left join (select CoutName,sum(Number) as OutNumbe from 从表 group by CoutName) b on a.CoutName=a.CoutName
#7
select a.CoutName ,
sum(case when a.Type='收货' then b.Number else 0 end) as InNumber,
sum(case when a.Type='退货' then b.Number else 0 end) as OutNumber
from T_Bill a,T_BillDetail b
where a.BillCode=b.BillCode
--其他日期条件等自己加
group by a.CoutName
#8
没测试过代码
#9
2.0版
select temp1.CoutName,temp1.InNumber,temp2.OutNumber
from (select CoutName,sum(Number) InNumber from a,c where a.BillCode=c.BillCode and Type='收货' group by CoutName) temp1
full join (select CoutName,sum(Number) OutNumber from a,c where a.BillCode=c.BillCode and Type='退货' group by CoutName) temp2
on temp1.CoutName=temp2.CoutName
#10
TO:lhylhy
经过变形,结合我的实际应该是这样的语句,但是老是提示“未指定的错误”
经过变形,结合我的实际应该是这样的语句,但是老是提示“未指定的错误”
SQLStr := 'select temp1.CoutName As coutname,temp1.TInNumber as TInNumber,temp2.TOutNumber as TOutNumber'+
'from (select a.CoutName As CoutName,sum(c.TNumber) As TInNumber from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.Identifier='+'''采购收货'''+' group by a.CoutName) temp1 '+
'full join (select a.CoutName As CoutName,sum(c.TNumber) As TOutNumber from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.Identifier='+'''采购退货'''+' group by a.CoutName) temp2 '+
'on temp1.CoutName=temp2.CoutName ';
#11
TO:ron_xin,同样是“未指定的错误”
SQLStr := 'select a.CoutName ,'+
'sum(case when a.Identifier='+''''+'采购收货'+''''+' then b.TNumber else 0 end) as TInNumber,'+
'sum(case when a.Identifier='+''''+'采购退货'+''''+' then b.TNumber else 0 end) as TOutNumber '+
'from T_Bill a,T_BillDetail b '+
'where a.BillCode=b.BillCode '+
//--其他日期条件等自己加
'group by a.CoutName ';
#12
汗,从第一句,转成现在这么一句强!
=================================
看不出错来.:> 算路过.
=================================
看不出错来.:> 算路过.
#13
有的数据库好像不用as,至少在某些地方不用,你用的是什么数据库?
#14
我用的是access,as是支持的,我在最简单的SQL语句中试过:
上面的语句就运行得很好,就是不能多插入另外两列,让用户知道退货的情况。
SQLStr := 'Select A.CoutName,Sum(B.TNumber) As TNumber,'+
'Sum(B.Price*B.TNumber) As TMoney From T_Bill A '+
'Left Join T_BillDetail B On A.BillCode=B.BillCode '+
'where A.Identifier = '+''''+'采购收货'+''''+ ' '+
'and addDate between :StartDate and :EndDate '+
'Group By A.CoutName';
上面的语句就运行得很好,就是不能多插入另外两列,让用户知道退货的情况。
#15
SQLStr := 'Select A.CoutName,Sum(B.TNumber) As TNumber,Sum(B.Price*B.TNumber) As TMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName';
如果这一句能行的话,那你就这样的吧
SQLStr := '(Select A.CoutName,Sum(B.TNumber) As TNumber,Sum(B.Price*B.TNumber) As TMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)';
SQLStr:= ' union '
SQLStr := '(Select A.CoutName,Sum(B.TNumber) As TNumber,Sum(B.Price*B.TNumber) As TMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购退货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)';
把二表连起来....不过.这种效率比较低.能用SELECT语句尽量用一句.
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName';
如果这一句能行的话,那你就这样的吧
SQLStr := '(Select A.CoutName,Sum(B.TNumber) As TNumber,Sum(B.Price*B.TNumber) As TMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)';
SQLStr:= ' union '
SQLStr := '(Select A.CoutName,Sum(B.TNumber) As TNumber,Sum(B.Price*B.TNumber) As TMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购退货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)';
把二表连起来....不过.这种效率比较低.能用SELECT语句尽量用一句.
#16
SQLStr := '(Select A.CoutName,Sum(B.TNumber) As TOutNumber,Sum(B.Price*B.TNumber) As TOutMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购退货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)';
SQLStr:= SQLStr +' union ' ;
SQLStr := SQLStr + '(Select A.CoutName,Sum(B.TNumber) As TInNumber,Sum(B.Price*B.TNumber) As TInMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)';
这个语句,只能计算前面的部分,后门的收货也是显示不出来,反之,为止掉乱一下也是一样的。
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购退货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)';
SQLStr:= SQLStr +' union ' ;
SQLStr := SQLStr + '(Select A.CoutName,Sum(B.TNumber) As TInNumber,Sum(B.Price*B.TNumber) As TInMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)';
这个语句,只能计算前面的部分,后门的收货也是显示不出来,反之,为止掉乱一下也是一样的。
#17
呵呵,没有数据表,只能猜着做.
================================
SQLStr := 'select * form ( (Select A.CoutName,Sum(B.TNumber) As TOutNumber,Sum(B.Price*B.TNumber) As TOutMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购退货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName) ) as a';
SQLStr:= SQLStr +' union ' ;
SQLStr := SQLStr + 'select * from ( (Select A.CoutName,Sum(B.TNumber) As TInNumber,Sum(B.Price*B.TNumber) As TInMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)) as b';
你这样再试试.把二个查询语句的结果变成二张表,然后连起来.得到一张整表.
================================
SQLStr := 'select * form ( (Select A.CoutName,Sum(B.TNumber) As TOutNumber,Sum(B.Price*B.TNumber) As TOutMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购退货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName) ) as a';
SQLStr:= SQLStr +' union ' ;
SQLStr := SQLStr + 'select * from ( (Select A.CoutName,Sum(B.TNumber) As TInNumber,Sum(B.Price*B.TNumber) As TInMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)) as b';
你这样再试试.把二个查询语句的结果变成二张表,然后连起来.得到一张整表.
#18
TO:nbzip
错误提示:不正常地定义参数对象。提供了不一致或不完整的信息。
其实这个问题,如果使用一个物理的临时表,做起来是很简单的,只要把两次的查询结果插入到物理临时表中,然后再Group By一次,但是我现在希望这些数据都存放在内存中。我使用了TADOQuery作为TDataSource的dataset,而不是TADOTable作为dataset。我希望达到的效果是,精简数据库的结构,尽量放弃使用物理表作为临时表,因为如果查询的显示形式越多,需要的物理临时表就愈多,这个我希望尽量避免。
错误提示:不正常地定义参数对象。提供了不一致或不完整的信息。
其实这个问题,如果使用一个物理的临时表,做起来是很简单的,只要把两次的查询结果插入到物理临时表中,然后再Group By一次,但是我现在希望这些数据都存放在内存中。我使用了TADOQuery作为TDataSource的dataset,而不是TADOTable作为dataset。我希望达到的效果是,精简数据库的结构,尽量放弃使用物理表作为临时表,因为如果查询的显示形式越多,需要的物理临时表就愈多,这个我希望尽量避免。
#19
SQLStr := 'select a.CoutName ,'+
'sum(case when a.Identifier='+''''+'采购收货'+''''+' then b.TNumber else 0 end) as TInNumber,'+
'sum(case when a.Identifier='+''''+'采购退货'+''''+' then b.TNumber else 0 end) as TOutNumber '+
'from T_Bill a,T_BillDetail b '+
'where a.BillCode=b.BillCode '+
//--其他日期条件等自己加
'group by a.CoutName ';
============================================跟据上面这句,我用自己的表,试了一下,没什么问题啊.
SELECT dept,sum(CASE WHEN ind=1 THEN p_qty ELSE 0 END) AS q1,sum(CASE WHEN ind=8 THEN p_qty ELSE 0 END) AS q2
FROM wh_in WHERE y=2009 GROUP BY dept
只是我的是一张表,你的是二张合在一起的一张表. 你自己再查查哪里写的有问题.噢我用的是MS SQL2005
select * from (select a.countname,a.identifier,b.tnumber from T_Bill a left join T_BillDetail b on a.bill_code=b.bill_code) as a
如果还不行,你把结果集转成一张表,然后再统计一下试试.
'sum(case when a.Identifier='+''''+'采购收货'+''''+' then b.TNumber else 0 end) as TInNumber,'+
'sum(case when a.Identifier='+''''+'采购退货'+''''+' then b.TNumber else 0 end) as TOutNumber '+
'from T_Bill a,T_BillDetail b '+
'where a.BillCode=b.BillCode '+
//--其他日期条件等自己加
'group by a.CoutName ';
============================================跟据上面这句,我用自己的表,试了一下,没什么问题啊.
SELECT dept,sum(CASE WHEN ind=1 THEN p_qty ELSE 0 END) AS q1,sum(CASE WHEN ind=8 THEN p_qty ELSE 0 END) AS q2
FROM wh_in WHERE y=2009 GROUP BY dept
只是我的是一张表,你的是二张合在一起的一张表. 你自己再查查哪里写的有问题.噢我用的是MS SQL2005
select * from (select a.countname,a.identifier,b.tnumber from T_Bill a left join T_BillDetail b on a.bill_code=b.bill_code) as a
如果还不行,你把结果集转成一张表,然后再统计一下试试.
#20
数据源其实是一张表,以单价类别字段来区分业务类型,通过提取方向操作的两个相对应的业务来得出如上图中的结果。
#21
数据源其实是一张表,以单据类别字段来区分业务类型,通过提取反向操作的两个相对应的业务来得出如上图中的结果。
#22
呵呵,我们调试程序,先尽快把答案给得到.只要能得到,就行.不要管如何得到.
然后,下部就是优化程序. 你暂时不要管别人如何得到结果,你只要得到对的结果.然后对这种结果再行优化.
(如果你得不到答案,可能就不能尽入下一步开发.你可以先得到差的答案,然后,再提问,然后你自己做下步,最后,
你得到答案或别人处得到答案,再心量的分析,优化.写入自己程序,然后提交任务.)
然后,下部就是优化程序. 你暂时不要管别人如何得到结果,你只要得到对的结果.然后对这种结果再行优化.
(如果你得不到答案,可能就不能尽入下一步开发.你可以先得到差的答案,然后,再提问,然后你自己做下步,最后,
你得到答案或别人处得到答案,再心量的分析,优化.写入自己程序,然后提交任务.)
#23
我现在也可以讲属于优化阶段了
使用
SQLStr := 'Select A.CoutName,Sum(B.TNumber) As TNumber,Sum(B.Price*B.TNumber) As TMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName';
可以得到一半的结果,
再使用
SQLStr := SQLStr + '(Select A.CoutName,Sum(B.TNumber) As TInNumber,Sum(B.Price*B.TNumber) As TInMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)';
又得到了一半的结果
,再把两个表格Group By A.CoutName 那么就得到了上图的效果了
我现在希望了解能不能不使用临时表的情况下,完成这个事情,这样的话,数据库的表就更少了。
使用
SQLStr := 'Select A.CoutName,Sum(B.TNumber) As TNumber,Sum(B.Price*B.TNumber) As TMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName';
可以得到一半的结果,
再使用
SQLStr := SQLStr + '(Select A.CoutName,Sum(B.TNumber) As TInNumber,Sum(B.Price*B.TNumber) As TInMoney '+
' From T_Bill A Left Join T_BillDetail B On A.BillCode=B.BillCode '+
' where A.Identifier = '+''''+'采购收货'+''''+ ' '+'and addDate between :StartDate and :EndDate '+'Group By A.CoutName)';
又得到了一半的结果
,再把两个表格Group By A.CoutName 那么就得到了上图的效果了
我现在希望了解能不能不使用临时表的情况下,完成这个事情,这样的话,数据库的表就更少了。
#24
TO:nbzip ,很感谢您的忠告,我在实际上,也是这么想这么做的。经过方法不好,但是能达到目的是最要紧的,方法以后可以改进。但是有时候做起程序也很较真,希望懂得更多,也希望尝试不同的方法达到目的。
#25
其他地方用form子查询正常吗?
#26
正常啊,我都没有进行过其他的查询,直接进入那里的。
#27
而且,我使用的是一个独立的TADOQuery,而不是公共TADOQuery,上面已经说明了,只提取一个类型的单据,运行结果是正确的,现在希望分类型提取结果,并显示在一个查询结果里。
#28
我是说像我写的那样,在form子句里有一个子查询的sql,一般子查询都是在where子句,会不会对form子句里的子查询的支持有问题?
#29
很有可能,这就解释了为什么连接两个子表后为什么只能查询出前面部分的内容,而显示不了后面部分。
#30
procedure TfrmCgGysHz.rzbtbtnViewClick(Sender: TObject);
var
SQLStr : string;
begin
//产生dbgrideh的字段
gsDrawDBGridEhTitle(frmDM.qryAll, dbgrdhCgGysHz, 'CgGysHz', frmDM.dsCgGysHz);
with frmDM.qryTmp do
begin
//取消dbgrideh的数据关联
dbgrdhCgGysHz.DataSource := nil;
Close;
SQL.Clear;
SQL.Add('delete * from CgGysHz'); //删除物料临时表的内容
ExecSQL;
//汇总采购收货单价的进货数量和金额
SQLStr := 'Select A.CoutName As CoutName,Sum(B.TNumber) As TInNumber,'+
'Sum(B.Price*B.TNumber) As TInMoney From T_Bill A '+
'Left Join T_BillDetail B On A.BillCode=B.BillCode '+
'where A.Identifier = '+''''+'采购收货'+''''+ ' '+
'and addDate between :StartDate and :EndDate '+
'Group By A.CoutName';
Close;
SQL.Clear;
SQL.Add(SQLStr);
Parameters.ParamByName('StartDate').Value:=edtBegin.Value;
Parameters.ParamByName('EndDate').Value:=edtEnd.Value;
Open;
//把采购收货的数据插入到物料临时表
SQLStr := 'insert into CgGysHz(CoutName,TInNumber,TInMoney) values('+
Quotedstr(FieldByName('CoutName').AsString)+
','+Quotedstr(fieldbyname('TInNumber').AsString)+
','+Quotedstr(fieldbyname('TInMoney').AsString)+')' ;
while not Eof do
begin
with frmDM.qryAll do
begin
Close;
SQL.Clear;
SQL.Add(SQLStr);
ExecSQL;
end;
Next;
end;
//汇总采购退货单据的进货数量和金额
SQLStr := 'Select A.CoutName As CoutName,Sum(B.TNumber) As TOutNumber,'+
'Sum(B.Price*B.TNumber) As TOutMoney From T_Bill A '+
'Left Join T_BillDetail B On A.BillCode=B.BillCode '+
'where A.Identifier = '+''''+'采购退货'+''''+ ' '+
'and addDate between :StartDate and :EndDate '+
'Group By A.CoutName';
Close;
SQL.Clear;
SQL.Add(SQLStr);
Parameters.ParamByName('StartDate').Value:=edtBegin.Value;
Parameters.ParamByName('EndDate').Value:=edtEnd.Value;
Open;
//把采购退货的数据插入到物料临时表
SQLStr := 'insert into CgGysHz(CoutName,TOutNumber,TOutMoney) values('+
Quotedstr(FieldByName('CoutName').AsString)+
','+Quotedstr(fieldbyname('TOutNumber').AsString)+
','+Quotedstr(fieldbyname('TOutMoney').AsString)+')' ;
while not Eof do
begin
with frmDM.qryAll do
begin
Close;
SQL.Clear;
SQL.Add(SQLStr);
ExecSQL;
end;
Next;
end;
//刷新物料临时表的内容
frmDM.tblCgGysHz.Active := False;
frmDM.tblCgGysHz.Active := True;
//汇总进货和退货的数据
SQLStr := 'Select A.CoutName,sum(A.TInNumber) As TInNumber,'+
'sum(A.TInMoney) As TInMoney,sum(A.TOutNumber) As TOutNumber,sum(A.TOutMoney) As TOutMoney '+' From CgGysHz A '+
'Group By A.CoutName';
Close;
SQL.Clear;
SQL.Add(SQLStr);
Open;
//建立dbgrideh的数据关联
dbgrdhCgGysHz.DataSource := frmDM.dsRptCenter;
end;
//刷新dbgrideh的数据
dbgrdhCgGysHz.DataSource.DataSet.Active := False;
dbgrdhCgGysHz.DataSource.DataSet.Active := True;
end;
这个就是使用物料临时表的代码,要达到问题给出的效果,使用物理临时表,不但繁琐,而且效率很低很低!!!
#31
我使用的是Access数据库,大家可能使用MSSQL做的测试,我试了一下
这个语句在MSSQL中就可以得到我要的结果!!晕!为什么在Access中就不行呢!
select
temp1.CoutName,temp1.TInNumber,temp1.TInMoney,temp2.TOutNumber,temp2.TOutMoney
from
(select a.CoutName As CoutName,sum(c.TNumber) As TInNumber,Sum(c.Price*c.TNumber) As TInMoney from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.Identifier='采购收货' group by a.CoutName) temp1
full join
(select a.CoutName As CoutName,sum(c.TNumber) As TOutNumber,Sum(c.Price*c.TNumber) As TOutMoney from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.Identifier='采购退货' group by a.CoutName) temp2
on
temp1.CoutName=temp2.CoutName
这个语句在MSSQL中就可以得到我要的结果!!晕!为什么在Access中就不行呢!
#32
full join 使用正常吗?会不会是access不支持full join?
#33
下面的在MSSQL上也可以执行!狂晕!~~
SQLStr := 'select a.CoutName ,'+
'sum(case when a.Identifier='+''''+'采购收货'+''''+' then b.TNumber else 0 end) as TInNumber,'+
'sum(case when a.Identifier='+''''+'采购退货'+''''+' then b.TNumber else 0 end) as TOutNumber '+
'from T_Bill a,T_BillDetail b '+
'where a.BillCode=b.BillCode '+
'and addDate between :StartDate and :EndDate '+
'group by a.CoutName ';
#34
反正大家给我的语句在MSSQL上好像都有结果,这个恐怕是delphi的Access驱动有问题,也可能是delphi2009 sp4本身的bug。原来听讲它的数据库驱动有bug,我没有碰到过,所以不是很相信,也不以为然,现在看来真有那么一回事!倒!~
#35
这个是完全符合要求的语句,但是只在MSSQL上可用,在ACCESS上提示“示知的错误”!!
SQLStr := 'select a.CoutName ,'+
'sum(case when a.Identifier='+''''+'采购收货'+''''+
' then b.TNumber else 0 end) as TInNumber,'+
'sum(case when a.Identifier='+''''+'采购收货'+''''+
' then b.Price*b.TNumber else 0 end) as TInMoney,'+
'sum(case when a.Identifier='+''''+'采购退货'+''''+
' then b.TNumber else 0 end) as TOutNumber,'+
'sum(case when a.Identifier='+''''+'采购退货'+''''+
' then b.Price*b.TNumber else 0 end) as TOutMoney '+
'from T_Bill a,T_BillDetail b '+
'where a.BillCode=b.BillCode '+
'and addDate between :StartDate and :EndDate '+
'group by a.CoutName ';
with frmDM.qryTmp do
begin
Close;
SQL.Clear;
SQL.Add(SQLStr);
Parameters.ParamByName('StartDate').Value:=edtBegin.Value;
Parameters.ParamByName('EndDate').Value:=edtEnd.Value;
Open;
end;
#36
已查明,access不支持FULL JOIN
#37
(select
temp1.CoutName,temp1.TInNumber,temp1.TInMoney,temp2.TOutNumber,temp2.TOutMoney
from
(select a.CoutName As CoutName,sum(c.TNumber) As TInNumber,Sum(c.Price*c.TNumber) As TInMoney
from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.Identifier='采购收货' group by a.CoutName) temp1
left join
(select a.CoutName As CoutName,sum(c.TNumber) As TOutNumber,Sum(c.Price*c.TNumber) As TOutMoney
from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.Identifier='采购退货' group by a.CoutName) temp2
on
temp1.CoutName=temp2.CoutName)
UNION
(select
temp2.CoutName,temp1.TInNumber,temp1.TInMoney,temp2.TOutNumber,temp2.TOutMoney
from
(select a.CoutName As CoutName,sum(c.TNumber) As TInNumber,Sum(c.Price*c.TNumber) As TInMoney
from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.Identifier='采购收货' group by a.CoutName) temp1
right join
(select a.CoutName As CoutName,sum(c.TNumber) As TOutNumber,Sum(c.Price*c.TNumber) As TOutMoney
from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.Identifier='采购退货' group by a.CoutName) temp2
on
temp1.CoutName=temp2.CoutName)
试一试
#38
TO:lhylhy
这个语句终于可以汇总了,但是不知道怎么添加时间区间的变量?如果SQL语句中使用两次就会报错的。
这个语句终于可以汇总了,但是不知道怎么添加时间区间的变量?如果SQL语句中使用两次就会报错的。
#39
SQLStr := '(select '+
'temp1.CoutName,temp1.TInNumber,temp1.TInMoney,temp2.TOutNumber,temp2.TOutMoney '+
'from '+
'(select a.CoutName As CoutName,sum(c.TNumber) As TInNumber,Sum(c.Price*c.TNumber) As TInMoney '+
'from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.addDate between :StartDate and :EndDate and a.Identifier='+'''采购收货'''+' group by a.CoutName) temp1 '+
'left join '+
'(select a.CoutName As CoutName,sum(c.TNumber) As TOutNumber,Sum(c.Price*c.TNumber) As TOutMoney '+
'from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.addDate between :StartDate and a.Identifier='+'''采购退货'''+' group by a.CoutName) temp2 '+
'on '+
'temp1.CoutName=temp2.CoutName) '+
'UNION '+
'(select '+
'temp2.CoutName,temp1.TInNumber,temp1.TInMoney,temp2.TOutNumber,temp2.TOutMoney '+
'from '+
'(select a.CoutName As CoutName,sum(c.TNumber) As TInNumber,Sum(c.Price*c.TNumber) As TInMoney '+
'from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.addDate between :StartDate and a.Identifier='+'''采购收货'''+' group by a.CoutName) temp1 '+
'right join '+
'(select a.CoutName As CoutName,sum(c.TNumber) As TOutNumber,Sum(c.Price*c.TNumber) As TOutMoney '+
'from T_Bill a,T_BillDetail c where a.BillCode=c.BillCode and a.addDate between :StartDate and a.Identifier='+'''采购退货'''+' group by a.CoutName) temp2 '+
'on '+
'temp1.CoutName=temp2.CoutName) ';
with frmDM.qryTmp do
begin
Close;
SQL.Clear;
SQL.Add(SQLStr);
Parameters.ParamByName('StartDate').Value:=edtBegin.Value;
Parameters.ParamByName('EndDate').Value:=edtEnd.Value;
Open;
end;
加上时间区间,仍然只计算前面的内容。
#40
时间是不是应该都写成这样
(a.addDate between :StartDate and :EndDate)
#41
SQLStr := 'select a.CoutName ,'+
'sum(iif( a.Identifier='+''''+'采购收货'+''''+
' ,b.TNumber , 0 )) as TInNumber,'+
'sum(iif (a.Identifier='+''''+'采购收货'+''''+
' ,b.Price*b.TNumber ,0 )) as TInMoney,'+
'sum(iif ( a.Identifier='+''''+'采购退货'+''''+
' ,b.TNumber ,0 )) as TOutNumber,'+
'sum(iif ( a.Identifier='+''''+'采购退货'+''''+
' ,b.Price*b.TNumber ,0 )) as TOutMoney '+
'from T_Bill a,T_BillDetail b '+
'where a.BillCode=b.BillCode '+
'and addDate between :StartDate and :EndDate '+
'group by a.CoutName ';
在SQL板块,某个高人写的,恐怕这个是答案了。
#42
TO:lhylhy
严格起来可能需要这样,但是我现在只有主表有adddate字段,所以程序仍然正确识别的。
严格起来可能需要这样,但是我现在只有主表有adddate字段,所以程序仍然正确识别的。