请大家帮我写一条将表中记录改做字段的Sql!(80分)

  • 主题发起人 主题发起人 fangyan
  • 开始时间 开始时间
F

fangyan

Unregistered / Unconfirmed
GUEST, unregistred user!
No1
我有一个Paradox表Main.Db,字段及内容如下:
AA(N) n1 n2 n3 n4 n5 (I)
1 0 8 6 5 5
2 4 5 2 3 1
3 5 3 7 8 1
. . . . . .
. . . . . .
其中AA由1开始随记录增长而增长
n1..n5的值由0..9构成
现在,需要用将Main.Db中记录Sql为如下格式:
Time1 Time2 Time3 . . . .
0 4 5
8 5 3
6 2 7
5 3 8
5 1 1
即Sql结果中的字段将随Mian.Db的AA字段的增长而增长
No2
对不起,附带再问一个问题:
在一个Sql查询的结果的最后,我想手动插入一条记录,应该如何做?

先在这里谢谢大家了!!!
 
好像没有这样的SQL可以这样
用一个Table1连接Main.db
用Table2连接Timer
Table1.Open;
Table2.Open;
Table1.First;
While not Table1.Eof do
begin
Table2.Insert;
Table2.FieldByName('Timer1').Value:=Table1.FieldByName('n1').Value;
Table2.FieldByName('Timer2').Value:=Table1.FieldByName('n2).Value;
.....
Table1.Next;
end;
Table2.Post;
然后在相应的DBGrid中显示Table2就可以了。
 
select x into newdb.db from main.db
x=n1,n2,...
但我不知道你的MAIN。DB是不是会动态增加纪录,还是数据不变,
涉及到动态增加列的问题。
 
写的不太清楚 @_@
 
补充一下用Query查询出来的表可能不能在DBGrid中直接插入,在没有细表的情
况下可能也可以。我的解决办法是再加一个Query专用来进行插入。不过想直接在
DBGrid中输入,不太好办不知别人有什么高招。插入还是用Table吧。
 
嘿嘿,第一个问题的答案是:不好办。
如果你想构造这样一个查询结果并且放到TDataSet里的话,
我看比较方便的方法是自己做一个专门的TDataSet的派生内,用来将行与列转置,
当然这个难度也不算小了:)
所以如果你想把查询结果用个DBGRID显示的话呢,
我觉得还不如直接用个TStringGrid,然后取出数据后自己加到StringGrid里面。

第二个问题嘛,
如果是个普通的SQL查询,那么设置TQuery控件的RequestLive 为 True,
然后执行TQuery.Insert,但要注意不是所有的SQL查询都是可修改的!
相关资料见DELPHI里面带的LOCALSQL.HLP
 
>>2.可以:不过Query的RequestLive设为True,然后:
query1.InsertRecord(['中国','北京','亚洲',96000,100000]);
以Delphi自带的dbdemos数据库Country表为例.
 
1.动态创建一张表,表的列数就是元表的行数
{
x:=table1.field[1].value//把表1的第一列读到一个数组里
table1.next
}


table2.field.value:=x//把数组值给表2的某条记录
2.创建另外一张表,把结果保存进去,这样就可以增删改了
 
不好意思没看清上面写错了
 
也许用一个中间矩阵更快一点,delphi5.0支持动态数组
我想可以解决问题
第二个问题,如果是多表查询出来的,恐怕不好办
另外建表,如果只是表面文章的话
单表查询的话,没有问题,用sql语句写到数据库中
然后,再次查询即可
 
没想到这么快就得到了大家的回应,再次谢谢大伙儿啦!^&^
关于问题的进一步说明:
No1
Main.Db中的记录是动态增加的。正如youtoo大侠所说!所以,需要
随Main.Db 中记录增加,在Timer.Db(Fencer取的表名,就用他好了!)
中的字段动态的随Main.Db的记录增加而增加。即:将Main.Db中AA的
值作为Timer.Db的字段名。
呵呵,真不好描述,也不知大侠们理解我的意思没有?简言之,即如何将
表中记录X,Y轴互换!
另:lhxu,能否将您说的方法再说的详细一点,能否附上源码?

No2
是从一个表中Sql一定条件的记录,然后在这些记录尾插入一条手工的
记录,形成的新结果在进行另外的Sql操作!
真的很感激大家的支持,谢谢!

 
No1:
你的意思是很明显的,就是将列当行,行当列,
不过用临时表的方法不一定行,所有的数据库都有域个数的限制
所以比较容易的方法是从界面上下功夫
对了,有个DevExpress Memory DataSet的控件,也许能帮你的忙
你可以将数据从数据库中取出后放到MemoryDataSet中,当然要自己动态地建TField对象

No2:
这回你的意思就不那么明显了,新加的记录要放回库中吗?
要放回去的话前面各位大侠(不含我,呵呵)不是都说了很多了?
要是不放回去的话呢,呵呵,就不好办了,没法子对一个TQuery缓冲区里面的数据进行SQL操作

 
关于NO2的紧急求助:
谢谢各位大侠,我按大侠们提供的思路,就第二个问题编制了一段代码,可是
在第一次手工添加了新记录后,第二次再执行时,上一次的记录仍然存在,可我
需要清空头一次Sql查询的记录,该怎样做?(代码如下;)
procedure TYuCe_F.SpeedButton1Click(Sender: TObject);
Var
TempAA : Integer ;
begin
With Query1 Do
Begin
Close ;
Sql.Clear ;
Sql.Add('Select AA,N'+inttostr(RxSlider1.Value)) ;
Sql.Add(' From Main') ;
Sql.Add(' Order By AA') ;
Try
Open
Except
execsql;
End; //Try End
Last ;
TempQishu := FieldValues['AA']+1 ;
InsertRecord([AA,RxSpinEdit1.Value]) ;
End ;
end;
 
最好把代码贴全。
1. 看不懂要求。
2. 看不出tempqishu有任何用处。
3. 这段代码只是取出main.db中的 AA字段和Nxxx字段,然后在最后添加
一条记录。
那么你的要求究竟是什么?
注意一点:
第二次调用时:
query1.close; --->清光所有缓冲区并关闭数据库.
以后的操作和第一次的操作完全一样. 当然得到的数据也完全一样了.
 
我明白了:-)
不过我想:
1. sql没有可以实现的类似语句:-(
2. 还是通过中转一下的方法好一些:
var
f: array of array of integer;
i,j: integer;
s: string;
begin
i:=0;
table1.first;
setlength(f,table1.fieldcount-1);
while not table1.eof do
begin
i:=i+1;
s:=s+ 'Time' +inttostr(fieldbyname('AA').asinteger)+' integer,'
if i>high(f[0]) then
for j:=low(f) to high(f) do
setlength(f[j],i);
for j:=0 to table1.fieldcount-2 do
f[j,i]:=table1.fields[j+1].asinteger;
table1.next;
end;
delete(s,length(s),1); //delete last ','
s:='create table table2 (' + s+ ')';
query1.sql.text:=s;
query1.execsql;
for i:=low(f) to high(f) do
begin
s:='insert into table2 values(';
for j:=low(f) to high(f) do
s:=s+ inttostr(f[i,j])+',';
delete(s,length(s),1); //delete last ','
s:=s+')';
query1.sql.text:=s;
query1.execsql;
end;
 
对不起大伙儿!
No2中代码中TempQiShu乃笔误,应为TempAA.
这个问题主要是我需动态加入一条记录(某商品销售数量),
来对某一商品销售的未来走势进行预测,Query1是配合DbChart来使用的。
我原意是想当再次Click SpeedButton1后,Query1数据完全清空,重新
根据条件的改变,进行新一轮Sql.
 
我必须加分,才对得起大家!+40
提一个新问题:
No3
我想利用Random产生随机数,但随机数是特定的几个数,
例如 有:9 3 5 6 ,要求就需在这4个数中产生,即
9 3 5 6 的排列组合!

No2的说明:
我并非是想将手工记录插入原表中,是想通过Sql产生出
一个临时表,将手工记录插入临时表中,利用临时表完成
相关工作后,需清空临时表,然后又完全重新依据新条件
Sql出新的记录。循环使用!

No1的说明:
cytown大侠的代码看来是可行的,但我调试了您提供的代码,
在Wihle循环体中第一次循环完成后,程序出错,不知何故?
另:CyTown打下,我的Main.Db字段如下:
AA n1 n2 n3 n4 n5 n6 n7 n8 Date FoodName
产生的新表结构如下:
Tiem1 Tiem2 Time3 Time4 Time5 Time6 Time7
麻烦您修改一下您的代码,主要是我的数组知识很弱智!
最好能附上一些简要注释,谢谢!
 
no3 如下:
var
math:array[0。。3]of integer
s1,s2,s3,s4:integer;
begin
s1:=random(3);
s1:=math[s1];


end;
math 是你所提供数的数组
 
啊蒙:
谢谢您,不过您的答案好象没有符合我的要求。Because:
var
math:array[0。。3]of integer
s1,s2,s3,s4:integer;
begin
s1:=random(3); //此时产生的随机数是0,1,2,3中的某个数
s1:=math[s1];
end;
而我所需的随机数是事先预定好的。比如:有4个数 9,3,5,6 随机数
就需要在这4个数中产生,而不能出现其它的数码。
不知我描述清楚没有?
 
no3:
var
i,j:integer;
k:strings;
s:string;
begin
k:=tstringlist.create;
k.text:='9' + #13#10+'3'+#13#10+'5'+#13#10+'6';
randomize;
for i:=k.count-1 downto 1 do
begin
j:=random(i);
s:=s + k.strings[j];
k.delete(j);
end;
s:=s + k.strings[0];
showmessage(s);
end;

no1:
先改:
setlength(f,table1.fieldcount-1);
//如果你有field不是n0....nx, 那么要减去: aa, date, fooname成为
setlength(f,table1.fieldcount-4);
后面..还是重写一下:
var
f: array of array of integer;
i,j: integer;
s: string;
begin
i:=0;
table1.first;
setlength(f,table1.fieldcount-4);
while not table1.eof do
begin
i:=i+1;
s:=s+ 'Time' +inttostr(fieldbyname('AA').asinteger)+' integer,'
if i>high(f[0]) then
for j:=low(f) to high(f) do
setlength(f[j],i);
for j:=0 to high(f) do
f[j,i]:=table1.fields[j+1].asinteger;
table1.next;
end;
delete(s,length(s),1); //delete last ','
s:='create table table2 (' + s+ ')';
query1.sql.text:=s;
query1.execsql;
for i:=low(f) to high(f) do
begin
s:='insert into table2 values(';
for j:=low(f) to high(f) do
s:=s+ inttostr(f[i,j])+',';
delete(s,length(s),1); //delete last ','
s:=s+')';
query1.sql.text:=s;
query1.execsql;
end;
end;
 

Similar threads

S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
900
SUNSTONE的Delphi笔记
S
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
后退
顶部