之二:简单的数据库,简单的表结构,简单的数据。-- 但这个SQL如何写,各位大侠请进。 (200分)

  • 主题发起人 主题发起人 白衣书生
  • 开始时间 开始时间

白衣书生

Unregistered / Unconfirmed
GUEST, unregistred user!
各位好:
数据库是Access的,表ABC中数据如下:
ID 工作号 工序 工时
1 01 a 1
2 01 b 2
3 01 c 1
4 01 a 1
5 02 b 1

要求SQL语句的结果为:
工作号 a工序工时 b工序工时 c工序工时 合计工时
01 2 2 1 5
02 0 1 0 1

以前看到过类似的问题,都解决了。
现在我这个却怎么也不正确了,只有求助各位了。
 
我的SQL是这样的:
Close;
SQL.Clear;
sss:= ' select 工作号,';
sss:=sss+'(select sum(工时) from ABC where 工序=a group by 工作号) as a工序工时';
sss:=sss+'(select sum(工时) from ABC where 工序=b group by 工作号) as b工序工时';
sss:=sss+'(select sum(工时) from ABC where 工序=c group by 工作号) as c工序工时';
sss:=sss+ 'from ABC';
sss:=sss+ 'group by 工作号';
SQL.Add(sss);
Open;

但是,子查询中要求只返回一个值,
即不能用group by (子查询就是这样了:select 工作号,sum(工时) from..... group by 工作号)
^^^^^^^^^^^^^^^^^^ ^^^^^^^^^
那么怎么改正??
 
01的b工序时有2个???
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=958574
 
对 01的b工序用了2个工时。
不过这个无关的。也有可能用1个或3个工时。
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=958574 已经看了。

有个不同之处,是他的那个按照年月分组,并且年月是指定好的。
我的这个ABC表中其实有很多记录,即工作号有很多的:01、02、03、04、05、06.....
不能一一指定,我总不能一一列出来吧。 所以想到只有用 “group by 工作号”分组了。
 
正如上面兄弟所说,你这不是一个附合交叉表查询标准的数据
解决起来有点麻烦,但是是可以解决的,
我还没想好
 
帮忙提提吧。
 
简单:
TRANSFORM Sum(工时) AS 工时之Sum
SELECT 工作号
FROM ABC
GROUP BY 工作号
PIVOT 工序;

合计工时 用计算字段实现
 
SuperLeo 老兄:
多谢老兄指教。 果然可以的。
小弟我学SQL不精,盼老兄详细讲解一下好吗。
TRANSFORM 何用?
PIVOT 又何解? 来龙去脉是怎么的?
是交叉表查询吗?
我是第一次这样用SQL,是不是Access 专用的?

盼老兄详细解释一下。多谢。
 
道理简单,但代码复杂,可能其它人有更好的办法,不过这个要求是达到了。

SELECT D.工作号, A.工时之Sum AS a工序工时, B.工时之Sum AS b工序工时, C.工时之Sum AS c工序工时, D.工时之Sum AS 合计工时
FROM (((SELECT tab.工作号, Sum(tab.工时) AS 工时之Sum
FROM tab
GROUP BY tab.工作号) D LEFT JOIN [SELECT tab.工作号, Sum(tab.工时) AS 工时之Sum
FROM tab
WHERE (((tab.工序)="a"))
GROUP BY tab.工作号]. AS A ON D.工作号 = A.工作号) LEFT JOIN [SELECT tab.工作号, Sum(tab.工时) AS 工时之Sum
FROM tab
WHERE (((tab.工序)="b"))
GROUP BY tab.工作号]. AS C ON D.工作号 = C.工作号) LEFT JOIN [SELECT tab.工作号, Sum(tab.工时) AS 工时之Sum
FROM tab
WHERE (((tab.工序)="b"))
GROUP BY tab.工作号]. AS B ON D.工作号 = B.工作号;
 
你可以看access关于交叉表的帮助!

另一招:合计工时不编程
在access中建一查询aaa:

SELECT abc.工作号, Sum(abc.工时) AS 工时之Sum
FROM abc
GROUP BY abc.工作号;

再用:
TRANSFORM Sum(abc.工时) AS 工时之Sum
SELECT abc.工作号, aaa.工时之Sum
FROM abc INNER JOIN aaa ON abc.工作号 = aaa.工作号
GROUP BY abc.工作号, aaa.工时之Sum
PIVOT abc.工序;

一步出结果.







 
to pyzfl :
多谢老兄指教。
谁说您只会灌水来着??? 我打他PP。 [:)]

我正在分析、学习您的代码。 多谢。
 
多谢 SuperLeo 老兄指点。 谢谢。
我正在测试。 完工后发分。

to all:真诚的谢谢大家。
 
这样更省一点,HZ是查询(TRANSFORM Sum(工时) AS 工时之Sum
SELECT 工作号
FROM ABC
GROUP BY 工作号
PIVOT 工序),也就是用了 SuperLeo 的交叉查询,但交叉查询不是标准SQL语句,所以
要做成ACCESS查询:

SELECT D.工作号, hz.a工序工时, hz.b工序工时, hz.c工序工时, D.工时之Sum AS 合计工时
FROM hz INNER JOIN [SELECT tab.工作号, Sum(tab.工时) AS 工时之Sum
FROM tab
GROUP BY tab.工作号]. AS D ON hz.工作号 = D.工作号;
 
其实用ACCESS的查询对象来做,确实是更好一点,真的不用编程!
 
各位老大:
查询结果是正确了。
但是我想引用这些结果,怎么指定字段名字,如给报表的字段赋值。

交叉查询 “TRANSFORM Sum(工时) AS 工时之Sum ”显示出工时合计,
但在 DBGrid中Title显示1、2、3、...,并不显示准确的字段名字。
那么我想用某一字段的查询值,应该怎么引用啊?
 
是啊,交叉表查询 + 分组求和,可以搞定的!

没空帮你写代码了,UP一下吧!
 
横表转竖表
 
selcect distinct d1.工作号 (select sum(工时) from abc d2 where d2.工作号=d1.工作号
and d2.工序='a') as a工序时间,
(select sum(工时) from abc d2 where d2.工作号=d1.工作号
and d2.工序='b') as b工序时间,
(select sum(工时) from abc d2 where d2.工作号=d1.工作号
and d2.工序='c') as c工序时间,
(select sum(工时) from abc d2 where d2.工作号=d1.工作号) as 合计工时
from abc d1
有点繁,但管用
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
S
回复
0
查看
739
SUNSTONE的Delphi笔记
S
S
回复
0
查看
749
SUNSTONE的Delphi笔记
S
后退
顶部