求教一个数据库的问题.
$frage$各位朋友, 你好.
小弟最近做一个有关Access数据库的作业时碰到一个计算和同个组件汇总的问题.具体如下:
A 产品 由 2个B1, 2个B2 和 2个A2构成
B1由3个C11 和 3个C12 组成
A2由3个B1 和 3个C12 组成
老师的要求是:
系统能够自动计算出: A 由2个B1, 8个B2 , 2个A2, 24个C11, 30个C12.
我自己设计的程序是分层计算.但相同的产品不会汇总:
第一层: 2个B1, 2个B2 和 2个A2
第二层: 在B1下面是6个C11 和 6个C12; A2下面是: 6个B1 和6个C12
第三层: 在B1 下面是18个C11, 和18个C12.
怎么样才能让我的程序汇总出A 是由2个B1, 8个B2 , 2个A2, 24个C11, 30个C12 构成的呢? 或者根本就不需要分成计算?? 如果是我,只能用SQL的子查询实现,Excel的实际应用我不太会。
看看有没有其他人能帮上忙,另外能否透露一下课名,这样大致有个方向。 :) 谢谢楼主的回帖! 我的课名是 Access 数据库的应用. 这里没有涉及到Excel. 请问楼主的"用SQL的子查询实现"能否具体点? 谢谢 比如 select colum1 from table1 where colum2 in (select colum2 from table2 where colum3 = ‘xxx’); 谢谢答复. 也许是我没有真的明白你的意思. 但是我觉得版主的主意好像很难实现.
因为我的产品构成表分10层, 而且有可能同一个构成部件不只在2层出现,有可能3层,4层甚至9层都有. 每层具有N多个不同或者相同的部件产品. 根据排列组合的道理 这里的重复的部件产品已经接近无穷多. 如果用select语句一个个写出有可能重复的情况, 好像已经接近不可能了.
我的愚蠢的原Select代码如下,希望各位好友能指点, 哪怕是批评, 建议也好. 谢谢
SELECT costitemQry.productname, costitemQry.productmenge, costitemQry.description, IIf(costitemQry! Is Null,Null,1) AS 1, costitemQry., costitemQry., * AS sum1, costitemQry., IIf(costitemQry! Is Null,Null,2) AS 2, costitemQry., costitemQry., * AS sum2, costitemQry., IIf(costitemQry! Is Null,Null,3) AS 3, costitemQry., costitemQry., * AS sum3, costitemQry., IIf(costitemQry! Is Null,Null,4) AS 4, costitemQry., costitemQry., * AS sum4, costitemQry., IIf(costitemQry! Is Null,Null,5) AS 5, costitemQry., costitemQry., * AS sum5, costitemQry., IIf(costitemQry! Is Null,Null,6) AS 6, costitemQry., costitemQry., * AS sum6, costitemQry., IIf(costitemQry! Is Null,Null,7) AS 7, costitemQry., costitemQry., * AS sum7, costitemQry., IIf(costitemQry! Is Null,Null,8) AS 8, costitemQry., costitemQry., * AS sum8, costitemQry., IIf(costitemQry! Is Null,Null,9) AS 9, costitemQry., costitemQry., * AS sum9, costitemQry., IIf(costitemQry! Is Null,Null,10) AS 10, costitemQry., costitemQry., * AS sum10, costitemQry.
FROM costitemQry
ORDER BY costitemQry.productname, costitemQry., costitemQry., costitemQry., costitemQry., costitemQry., costitemQry., costitemQry., costitemQry., costitemQry., costitemQry.;
$考虑$ 你说的十层是指10个表么? :) 10层是指有层次关系的产品构成. 比如如上面的Structure图: A产品由B1, B2 和 A2构成, 其中的B1, B2 和 A2就是第一层. B1下面的C11,C12就是第二层.
所有的产品基本上只放在一个表里面. 通过查询来实现它的功能.
我的Email: joed968@yahoo.com
05111325379
谢谢了 能否把表结构放上来瞧瞧? 不过偶不是学Info的,说不定其他学Info的学生不需要也能作出来,就当是把你顶了。 :) 很乐意把我做的丑东东传上来,但是好像回帖时是传不少附件的呢. 我试着做了一下,并在MySQL上测试,可以得出结果,但是有两个小问题:
1。楼主提供的答案:“2个B1, 8个B2”是不是弄反了?应该是2个B2, 8个B1吧。
2。题目有没有给定条件,说明A类只包括A1,A2两种,B类只包括B1,B2两种,C类也只包括两种,依此类推一直到第10层?如果没有提供这样的条件,这道题将必须通过编程实现,也就是说要不停的做深度探测,比如如下情况理路上都是可以发生的:A1下有A2,A2下有A3。。。An下才有一个B1;这样是无法手动通过SQL实现查询的。
我是假设题目给定条件,每个字幕只有两种类型,也就是说如楼主例子中的情况,只有X1和X2。
建表结构:
A表:
+------+------+
| name | link |
+------+------+
| A1 | B1 |
| A1 | B1 |
| A1 | B2 |
| A1 | B2 |
| A1 | A2 |
| A1 | A2 |
| A2 | B1 |
| A2 | B1 |
| A2 | B1 |
| A2 | C12|
| A2 | C12|
| A2 | C12|
| | |
+------+------+
B表:
+------+------+
| name | link |
+------+------+
| B1 | C11|
| B1 | C11|
| B1 | C11|
| B1 | C12|
| B1 | C12|
| B1 | C12|
+------+------+
查询A只需直接查询A表
查询A2:
SELECT * FROM A WHERE name="A1" AND link="A2";
查询B需要直接查询A表,以及A-A的链接
查询B1:
SELECT * FROM A WHERE name="A1" AND link="B1"
union all
SELECT A2.name, A2.link FROM A AS A1 INNER JOIN A AS A2 ON A1.link=A2.name WHERE A1.name="A1" AND A2.link="B1";
查询B2:
SELECT * FROM A WHERE name="A1" AND link="B2"
union all
SELECT A2.name, A2.link FROM A AS A1 INNER JOIN A AS A2 ON A1.link=A2.name WHERE A1.name="A1" AND A2.link="B2";
查询C需要直接查询A表,以及A-A,A-B表的链接,以及A-A-B,A-B-B,A-A-B-B
查询C11:
SELECT * FROM A WHERE name="A1" AND link="C11"
union all
SELECT A2.name, A2.link FROM A AS A1 INNER JOIN A AS A2 ON A1.link=A2.name WHERE A1.name="A1" AND A2.link="C11"
union all
SELECT A.name, B.link FROM A INNER JOIN B ON A.link=B.name WHERE A.name="A1" AND B.link="C11"
union all
SELECT A1.name, B.link FROM A AS A1 INNER JOIN A AS A2 ON A1.link=A2.name INNER JOIN B ON A2.link=B.name WHERE A1.name="A1" AND B.link="C11"
union all
SELECT A.name, B2.link FROM A INNER JOIN B AS B1 ON A.link=B1.name INNER JOIN B AS B2 ON B1.link=B2.name WHERE A.name="A1" AND B2.link="C11"
union all
SELECT A1.name, B2.link FROM A AS A1 INNER JOIN A AS A2 ON A1.link=A2.name INNER JOIN B AS B1 ON A2.link=B1.name INNER JOIN B AS B2 ON B1.link=B2.name WHERE A1.name="A1" AND B2.link="C11";
查询C12:
SELECT * FROM A WHERE name="A1" AND link="C12"
union all
SELECT A2.name, A2.link FROM A AS A1 INNER JOIN A AS A2 ON A1.link=A2.name WHERE A1.name="A1" AND A2.link="C12"
union all
SELECT A.name, B.link FROM A INNER JOIN B ON A.link=B.name WHERE A.name="A1" AND B.link="C12"
union all
SELECT A1.name, B.link FROM A AS A1 INNER JOIN A AS A2 ON A1.link=A2.name INNER JOIN B ON A2.link=B.name WHERE A1.name="A1" AND B.link="C12"
union all
SELECT A.name, B2.link FROM A INNER JOIN B AS B1 ON A.link=B1.name INNER JOIN B AS B2 ON B1.link=B2.name WHERE A.name="A1" AND B2.link="C12"
union all
SELECT A1.name, B2.link FROM A AS A1 INNER JOIN A AS A2 ON A1.link=A2.name INNER JOIN B AS B1 ON A2.link=B1.name INNER JOIN B AS B2 ON B1.link=B2.name WHERE A1.name="A1" AND B2.link="C12"; 探测深度可以用递归实现,例如
函数(节点){
if (节点.子节点都不属于同一个表格)
exit;
else{
数据库操作或者记录节点信息;
函数(节点.子节点);
}
} $送花$ 非常感谢cn1h的精彩答复! 你所指出的8个B1 和2个B2完全正确! 我后来也发现了这个问题,但是已经修改不了了.
在你设定的前提条件下,你的答复也很正确.非常感谢你的热心支持!
但是就像我在上面曾指出的: "产品构成表分10层, 而且有可能同一个构成部件不只在2层出现,有可能3层,4层甚至9层都有. 每层具有N多个不同或者相同的部件产品. 根据排列组合的道理 这里的重复的部件产品已经接近无穷多. 如果用select语句一个个写出有可能重复的情况, 好像已经接近不可能了."
而且,这个数据库是模拟厂家产品构成,组件计算的.实际的产品名称我们不可能都知道.即使都知道,以后的工厂生产过程中也可能增加别的零部件,那么我们的数据库又存在漏洞了.
所以小弟个人觉得我们不能定义寻找常量,只能寻找变量. 但是关于如何在数据库中寻找相同的变量并进行求和,我就只能请教各位高手了.
这段时间小弟都在日夜寻找这道题的答案.如果找到了.小弟一点公开.
再次谢谢cn1h大侠的指点!$握手$ 呵呵,我也是菜鸟,和你一起思考,我也能学到东西。
关于这个题目,我还是有些看不太懂。最好能给出数据库表的结构,这个厂商应该告诉的吧。
另外推荐你一个论坛,www.csdn.net那里是我知道的国内IT最专业的论坛,上面有很多牛人,不像我们学生,人家很多都是正在前线拼杀的专业人士。你可以去数据库板块问问。 如果各位朋友需要我的数据库,请把你的Email给我. 我真的不知道怎么样把我做的东东传到论坛上.:) 原帖由 joed 于 2007-1-9 11:30 发表
如果各位朋友需要我的数据库,请把你的Email给我. 我真的不知道怎么样把我做的东东传到论坛上.:)
其实如果是Access的话,你可以只把数据结构导出来,这样再压缩成rar或者Zip文件,理论上应该就可以上传了。
普通用户的上传限制好象是512k,我想如果只有表结构的话,应该没什么问题
祝你好运
$支持$ $支持$ 请问版主,我看不到哪里有上传的字样啊? if you have enough right, then you can see the button on the bottle of the reply window $郁闷$sorry, i don't have this right! i think i can find the Solution and i will make it public as soon as possible$辛苦$ $辛苦$ if you want, you can send the Data via email to me, and i post it then for you
:) :) hi.
这道题终于有个眉目了:
在窗体上设立4个按键:
Gesamt_Auflistung, Stufen_Auflistung, Übersichts_Auflistung, Neuanlage tblZielTest
然后输入如下代码就行了:
Option Compare Database
Option Explicit
Dim bGefunden As Boolean
Dim bEnde As Boolean
Dim RettSchluessel(99)
Dim RettOberElement(99) As String
Dim RettMultiplikator(99) As Integer
Dim iStufe As Integer
Dim i As Integer
Dim stDocName As String
Dim OrigRst As DAO.Recordset
Dim ZielRst As DAO.Recordset
Private Sub Gesamt_Auflistung_Click()
Bearb_Ziel
stDocName = "rptZiel_Gesamt"
DoCmd.OpenReport stDocName, acViewPreview
End Sub
Private Sub Bearb_Ziel()
bGefunden = False
bEnde = False
Set OrigRst = CurrentDb.OpenRecordset("tblOriginal")
Set ZielRst = CurrentDb.OpenRecordset("tblZiel")
' Loesche Zieltabelle "besonders quick and dirty"
Do Until ZielRst.EOF
ZielRst.Delete
ZielRst.MoveNext
Loop
iStufe = 0
RettMultiplikator(iStufe) = 1
' Lesen o-Datei mit Formularkey
OrigRst.Index = "OberElement"
OrigRst.Seek "=", Me.OberElement
If OrigRst.NoMatch Then
bEnde = True
Else
bGefunden = True
End If
Do Until bEnde
If bGefunden Then
' Schreiben Zieltabelle
ZielRst.AddNew
ZielRst!UnterElement = OrigRst!UnterElement
ZielRst!OrigAnzahl = OrigRst!Anzahl
If iStufe = 0 Then
ZielRst!Anzahl = OrigRst!Anzahl
Else
ZielRst!Anzahl = OrigRst!Anzahl
'Multiplikation der Mengen mit den Vorstufen
For i = iStufe To 1 Step -1
ZielRst!Anzahl = ZielRst!Anzahl * RettMultiplikator(iStufe - i)
Next
End If
ZielRst!Stufe = iStufe
ZielRst.Update
RettSchluessel(iStufe) = OrigRst.Bookmark
RettOberElement(iStufe) = OrigRst!OberElement
RettMultiplikator(iStufe) = OrigRst!Anzahl
End If
' Lesen Orig-Datei mit UE-Schluessel
OrigRst.Seek "=", OrigRst!UnterElement
If OrigRst.NoMatch Then
AltePosUndNaechsten
Else
bGefunden = True
iStufe = iStufe + 1
End If
Loop
OrigRst.Close
ZielRst.Close
End Sub
Private Sub AltePosUndNaechsten()
bEnde = False
bGefunden = False
Do Until bEnde = True Or bGefunden = True
OrigRst.Bookmark = RettSchluessel(iStufe)
OrigRst.MoveNext
If Not OrigRst.EOF Then
If OrigRst!OberElement = RettOberElement(iStufe) Then
bGefunden = True
Else
If iStufe > 0 Then
iStufe = iStufe - 1
Else
bEnde = True
End If
End If
Else
If iStufe > 0 Then
iStufe = iStufe - 1
Else
bEnde = True
End If
End If
Loop
End Sub
Private Sub Neuanlage_Click()
' Neuanlage tblZielTest
Dim conn As ADODB.Connection
Dim Info As Integer
Set conn = CurrentProject.Connection
' Pruefung des Zustandes eines Datenbankobjektes
' 0 = nicht geoeffnet oder nicht vorhanden
' 1 = geoeffnet
' 2 = geaendert, aber nicht gespeichertacSysCmdGetObjectState
' 4 = Neu
Info = SysCmd(acSysCmdGetObjectState, acTable, "tblZielTest")
'Select Case Info
'Case Is = 0
' Datei nicht vorhanden
' conn.Execute "DROP TABLE tblZielTest"
'Case Is = 1
' conn.Execute "DROP TABLE tblZielTest"
'Case Else
' MsgBox "Die Tabelle tblZielTest kann nicht geloescht werden"
'End Select
On Error GoTo Fehler
conn.Execute "DROP TABLE tblZielTest"
conn.Execute "CREATE TABLE tblZielTest " _
& "(Autowert Counter, " _
& "Unterelement char(10), " _
& "Anzahl Integer, " _
& "OrigAnzahl integer)"
Set conn = Nothing
GoTo FehlerEnde
Fehler:
Select Case Err.Number
Case Is = -2147217865
MsgBox "Datei war nicht vorhanden"
Resume Next
Case Else
Resume Next
End Select
FehlerEnde:
End Sub
Private Sub Stufen_Auflistung_Click()
Bearb_Ziel
stDocName = "rptZiel_Stufe"
DoCmd.OpenReport stDocName, acViewPreview
End Sub
Private Sub Uebersichts_Auflistung_Click()
Bearb_Ziel
stDocName = "rptZiel_uebersicht"
DoCmd.OpenReport stDocName, acViewPreview
End Sub
$ok$
页:
[1]