一条 SQL 语句能否处理 这样一种情况 (100分)

  • 主题发起人 主题发起人 sunqi
  • 开始时间 开始时间
S

sunqi

Unregistered / Unconfirmed
GUEST, unregistred user!
有两个相同结构数据库 如 :


编号,名称 ,类别 价格,数量 日期
01 1111 AAA 50 1 1999-05-03
02 3333 BBB 12 5 1998-05-02
03 2222 CCC 12 3 1997-08-03
04 1111 AAA 50 1 1999-05-03
。。。。。。。


编号,名称 ,类别 价格,数量 日期
01 8888 AAA 50 1 1999-05-03
02 1111 AAA 12 15 1998-05-02
03 9999 CCC 12 13 1997-08-03
04 7777 BBB 50 21 1999-05-03
。。。。。。。

现用一条SQL 语句 得到某个时间段两个库中按类别分类汇总各类别数量的
合计

 
看一下SQL HELP中的UNION
 
select id, sum(价格), sum(数量) where 日期>=:begindate and 日期<=:enddate
group by id.

下例对时间段外的数据也统计显示(ansi sql-92):
select id, case
when 日期<:begindate then 1
when 日期>=:begindate and 日期<=:enddate then 2
else 3
end as daterange, sum(价格), sum(数量) group by id, daterange
 
漏了from部分:
select a.id, sum(a.价格+b.价格), sum(a.数量+b.数量) from TableA a, TableB b
where (a.id = b.id) and (a.日期>=:begindate and a.日期<=:enddate
and b.日期>=:begindate and b.日期<=:enddate)
group by id.

select a.id, case
when a.日期<:begindate or b.日期<:begindate then 1
when a.日期>=:begindate and a.日期<=:enddate then 2
when b.日期>=:begindate and b.日期<=:enddate then 2
else 3
end as daterange, sum(a.价格+b.价格), sum(a.数量+b.数量)
from tableA a, tableb b where a.id = b.id
group by id, daterange
 
SELECT 数量,类别 FROM 表1 WHERE 日期>开始日期 AND 日期<结束日期
UNION
SELECT 数量,类别 FROM 表2 WHERE 日期>开始日期 AND 日期<结束日期
ORDER BY 类别
COMPUTE SUM(数量) BY 类别
 
silly 的方法我试了,但提示COMPUTE 不能识别,是否 我用的INTERBASE 不支持
该语法 。
ANOTHER-eyes 的方法我没有看明白 , A,ID=B,ID 如果A 表中的 类别,B表中
没有 该结果应该不对 ,请ANOTHER——EYES 再确认一下

 
怎么没人参加讨论了 ?
 
SELECT a.类别, SUM(a.数量) + SUM(b.数量) 数量
FROM a, b
WHERE a.类别 = b.类别 AND (日期 ...)
GROUP BY a.类别
UNION
SELECT 类别, SUM(数量) 数量
FROM a
WHERE 类别 NOT IN(SELECT 类别 FROM b) AND (日期 ...)
GROUP BY 类别
UNION
SELECT 类别, SUM(数量) 数量
FROM b
WHERE 类别 NOT IN(SELECT 类别 FROM a) AND (日期 ...)
GROUP BY 类别
ORDER BY 类别
 
因为SQL的From子句中不能再用除了Join之外子查询,
而只能引用已经存在的表或者已经命名的查询(视图)

所以不能只用一条SQL语句得到结果,必须用两条:
一条给出两个表的联合, 另一条给出分类统计的结果
另外,UNION 在这里应该加上参数,成为 UNION ALL


 
To Randolph:
您的语句试验过吗?我怎么觉得第一部分从两个表里面选择,Sum,
再Group by 类别,逻辑上不太对耶!例如,对b.数量的Sum
究竟作用到b表上面的那些元组上面?
 
试试看(没条件测试):
select a.id, b.id,
case
when a.日期<开始日期 or b.日期<开始日期 then 0
when a.日期>=开始日期 and a.日期<=结束日期 then 1
when b.日期>=开始日期 and b.日期<=结束日期 then 1
else 2
end as datepart, sum(a.数量)+sum(b.数量)
from tableA a full join tableB b
on (a.id = b.id)
group by a.id, b.id, datepart
having datepart = 1
 
to pegasus:
1. 除了日期, 其他都测试过;
2. 逻辑不太对, 却能正常工作 :)
3. 因为 a.类别 = b.类别 , 所以 GROUP BY a.类别 与 GROUP BY b.类别
同样.
 
1.可以先创建一个试图,把两个表合并。
create view view1 as
( select * from table1
union select * from table2
)
2.从一得到的试图中
select sum(数量 ) '合计','类别 '
from view1
group by '类别 '

做试图的好处在于,客户机负担轻,网络流量小,客户端程序简单。
 
To Randolph:
Nice!

不过还是创建一个视图,然后使用SQL语句效率高,而且也优美,
但是谁叫人家一定要求只能用一条SQL呢?

 
今天我对ANOTHER——EYES 的方法进行测试但不行,后查资料发现该语法适用于
SQL—SERVER 我用的是INTERBASE 因而没法校验其对错。
为什么用一条语句是考虑到多用户的问题 ,因为在多用户下,多用户同时操作,
创建临时表,就有表名不能重复和用完以后要散除,如果在计算中出现异常强行中断,就会产生许多临时表的问题,因而。。。。。
不知各位大虾是否遇到这类问题,能否赐教一下,请继续讨论


 
用视图的时候不是创建临时表的
 
VIEW 的创建是不能用UNION的,至少SYBASE SQL SERVER 如此,不知INTERBASE如何.
 
我以前用VB做过一些数据库项目,以下仅供参考:
1)若是一个数据库的两个表,可以如下:
select 类别,sum(数量) from 表1,表2 where ((起始日期<日期) and ( _
终止日期>日期))
2)若是两个数据库,可以有如下思路:
(1)打开第一个数据库;称为记录集1;select 类别,sum(数量) from 数据库1.表1
(2)打开第二个数据库;称为记录集2;select 类别,sum(数量) from 数据库2.表1
(3)统计两个记录集的类别总数及名称,将其付值到一个数组中,可以用一个变量
记下个数;
(4)最后可以如下:

for i=1 to 个数
建立记录集3:select sum(数量) from 数据库1.表1 where 类别=类别i
建立记录集4:select sum(数量) from 数据库2.表1 where 类别=类别i
最后结果(类别i的数量)=记录集3.数量+记录集4.数量
next
说明:最后相加时,必须对记录集3和记录集4进行检验(有数据且为合法数据)!
以上仅供参考!
 
多人接受答案了。
 
以上各位在回答sunqi的问题时都回避了一个最关键的环节,就是这个“日期”在程序里怎么赋值,比如sunqi在dbf中定义“日期”为date类型,我们定义如下
var s,e:string;
q:tdatetime;
begin
//统计目前到20日以前这段时间
e:=datetostr(now);
q:=now-20;
s:=datetostr(q);
SELECT 数量,类别 FROM 表1 a WHERE a.日期>s AND 日期<e
end;
程序是通不过的
 
后退
顶部