请教一个较复杂的SQL语句如何编写,数据库ACCESS

RedAngler 2008-03-06 11:06:32
数据库ACCESS,数据表gugan,表中有字段birthday(出生日期),whcd(文化程度),Rzz_time(任正职时间)等
文化程度分为:小学、初中、高中、中专、大专、本科、硕士、博士,在查询界面上用ComboBox提供让用户选择,
birthday和Rzz_time字段在表中均为datetime类型。

现在要求实现:
统计出年龄在40岁到50岁之间、文化程度中专到本科之间、任正职时间在3年到10年之间的所有人员,请问这样的SQL语句要如何编写?
...全文
170 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
RedAngler 2008-03-25
  • 打赏
  • 举报
回复
zhouzuoji,你连问题的需求都没看清楚就出言不逊,实在可恶!一点敬业精神都没有!多向cdsnghw学习学习吧!为什么同样一个问题,人家cdsnghw写出的程序不仅逻辑严密,而且很好地解决了问题呢?谁是白痴,我想你心里应该清楚吧?
非常感谢cdsnghw耐心的回答,本问题是我业余编程中碰到的一个问题,问题已经完全解决,结贴!
cdsnghw 2008-03-23
  • 打赏
  • 举报
回复
你复制过去修改的时候仔细一点,也可以不修改!

procedure TForm1.BitBtn4Click(Sender: TObject);
var
i,AgeFrom,AgeTo,RzzFrom,RzzTo : integer;
WhcdFrom,WhcdTo,SqlStr,whcds : string;

begin
SqlStr := '';//select * from gugan where
try
begin
//逻辑上你的错误:从你的代码看出,如果条件不正确设置,则认为是不进行条件限制 ,这是不对的,应该添加退出语句exit
{年龄查询条件处理}
//if (Trim(AgeFromEdit.Text)<>'') or (Trim(AgeToEdit.Text)<>'') then
//条件出错,应该用 and 而不是用 or
if (Trim(AgeFromEdit.Text)<>'') and (Trim(AgeToEdit.Text)<>'') then
begin
AgeFrom := StrToInt(trim(AgeFromEdit.Text));
AgeTo := StrToInt(trim(AgeToEdit.Text));
if AgeFrom>AgeTo then
begin
ShowMessage('年龄设置有问题,请重新检查');
AgeFromEdit.SetFocus;
exit;//添加
end
else if SqlStr='' then
SqlStr := 'now between dateadd(''yyyy'','+AgefromEdit.text+',birthday) and dateadd(''yyyy'','+AgeToEdit.text+',birthday)'
else
SqlStr := SqlStr+' and now between dateadd(''yyyy'','+AgefromEdit.text+',birthday) and dateadd(''yyyy'','+AgeToEdit.text+',birthday)';
end //应该加上else exit
;

{任正职时间查询条件处理}
//if (Trim(RzzFromEdit.Text)<>'') or (Trim(RzzToEdit.Text)<>'') then
if (Trim(RzzFromEdit.Text)<>'') and (Trim(RzzToEdit.Text)<>'') then
//条件出错,应该用 and 而不是用 or
begin
RzzFrom := StrToInt(trim(RzzFromEdit.Text));
RzzTo := StrToInt(trim(RzzToEdit.Text));
if RzzFrom>RzzTo then
begin
ShowMessage('查询条件<任职时间>设置有问题,请重新检查');
RzzFromEdit.SetFocus;
exit;//添加
end
else
begin
if SqlStr='' then
//条件语句错误修改
SqlStr :='now between dateadd(''yyyy'','+RzzFromEdit.text+',Rzz_time) and dateadd(''yyyy'','+RzztoEdit.text+',Rzz_time)'
else
//条件语句错误修改
SqlStr := Sqlstr+' and now between dateadd(''yyyy'','+RzzFromEdit.text+',Rzz_time) and dateadd(''yyyy'','+RzztoEdit.text+',Rzz_time)';
end;
end//应该加上else exit
;

{文化程度查询条件处理}
if (Trim(WhcdFromComboBox.Text)<>'') or (Trim(WhcdFromComboBox.Text)<>'') then
begin
WhcdFrom := trim(WhcdFromComboBox.Text);
WhcdTo := trim(WhcdToComboBox.Text);
if WhcdFromComboBox.ItemIndex>WhcdToComboBox.ItemIndex then
begin
ShowMessage('文化程度设置有问题,请重新检查');
WhcdFromComboBox.SetFocus;
exit;//添加
end
else
begin
whcds := '';
for i:=WhcdFRomComboBox.itemindex to WhcdToComboBox.itemindex do begin
//你没有按照我的原句子,出错,whcds:=whcds+','+''+WhcdFRomComboBox.items[i]+'''';
whcds:=whcds+','''+WhcdFRomComboBox.items[i]+'''';
end;
Delete(whcds,1,1);
//你没有按照我的加上下面一句
whcds:='('+whcds+')';
if SqlStr='' then
//你又错了 SqlStr :='whcd in+whcds'
SqlStr :='whcd in'+whcds
else
//你又错了 SqlStr := Sqlstr+'and whcd in+whcds';
SqlStr := Sqlstr+' and whcd in'+whcds;
end;
end//应该加上else exit
;


try
with DataModuleADO.ADOQuery1 do
begin
SQL.Clear;
if not (MessageDlg('你的查询条件是"'+sqlstr+'"',mtConfirmation, [mbYes, mbNo], 0) = mrYes) then exit;
//下面最重要的东西你忘记了
if sqlstr='' then sqlstr:='select * from gugan' else
sqlstr:='select * from gugan where '+sqlstr;

sql.add(trim(SqlStr));
//加上调试语句

{cdsnghw提供的SQL语串: sql.add('select * from gugan where now between dateadd(''yyyy'','+AgefromEdit.text+',birthday) and dateadd(''yyyy'','+AgeToEdit.text+',birthday) and now between dateadd(''yyyy'','+RzzFromEdit.text+',Rzz_time) and dateadd(''yyyy'','+RzztoEdit.text+',Rzz_time) and whcd in'+whcds);}

open;
DataSource1.DataSet:=DataModuleADO.ADOQuery1;
DbGrid1.DataSource:=DataSource1;
end;
except
MessageDlg('年龄、文化程度或任正职时间查询有误!',mtError,[mbok],0);
end;

end; //顶层try
except
MessageDlg('查询条件设置存在问题,请检查是否设置正确、完整!',mtError,[mbok],0);
end;
end;
cdsnghw 2008-03-23
  • 打赏
  • 举报
回复
sqlstr我根本找不到你在哪里有‘select’这个单词(注释调的我的语句以外)。
你的大量代码if SqlStr='' 没有意义,因为它应该初始化为
SqlStr := 'select * from gugan where ';
cdsnghw 2008-03-23
  • 打赏
  • 举报
回复
你需要学会调试,你的问题不仅是sql的问题,而更重要的是delphi的问题。
sql.add(trim(SqlStr));之后你应该加上一句调试语句:
showmessage(sqlstr);
UndefinedCoder 2008-03-23
  • 打赏
  • 举报
回复
统计出年龄在40岁到50岁之间、文化程度中专到本科之间、任正职时间在3年到10年之间的所有人员,请问这样的SQL语句要如何编写?

……………………………………………………………………………………………………………………………………
连OR和AND的关系都没说清楚。白痴一个。
wendream 2008-03-23
  • 打赏
  • 举报
回复
这个很复杂?
RedAngler 2008-03-20
  • 打赏
  • 举报
回复
我按cdsnghw的思路写了以下程序段,但还是不行,问题出在SQL语串上,请各高手帮我检查检查。


procedure TForm1.BitBtn4Click(Sender: TObject);

var
i,AgeFrom,AgeTo,RzzFrom,RzzTo : integer;
WhcdFrom,WhcdTo,SqlStr,whcds : string;

begin
SqlStr := '';
try
begin

{年龄查询条件处理}
if (Trim(AgeFromEdit.Text)<>'') or (Trim(AgeToEdit.Text)<>'') then
begin
AgeFrom := StrToInt(trim(AgeFromEdit.Text));
AgeTo := StrToInt(trim(AgeToEdit.Text));
if AgeFrom>AgeTo then
begin
ShowMessage('年龄设置有问题,请重新检查');
AgeFromEdit.SetFocus;
end
else if SqlStr='' then
SqlStr := 'now between dateadd(''yyyy'','+AgefromEdit.text+',birthday) and dateadd(''yyyy'','+AgeToEdit.text+',birthday)'
else
SqlStr := SqlStr+'and now between dateadd(''yyyy'','+AgefromEdit.text+',birthday) and dateadd(''yyyy'','+AgeToEdit.text+',birthday)';
end;

{任正职时间查询条件处理}
if (Trim(RzzFromEdit.Text)<>'') or (Trim(RzzToEdit.Text)<>'') then
begin
RzzFrom := StrToInt(trim(RzzFromEdit.Text));
RzzTo := StrToInt(trim(RzzToEdit.Text));
if RzzFrom>RzzTo then
begin
ShowMessage('查询条件<任职时间>设置有问题,请重新检查');
RzzFromEdit.SetFocus;
end
else
begin
if SqlStr='' then
SqlStr :='dateadd(''yyyy'','+RzztoEdit.text+',Rzz_time)'
else
SqlStr := Sqlstr+'and dateadd(''yyyy'','+RzztoEdit.text+',Rzz_time)';
end;
end;

{文化程度查询条件处理}
if (Trim(WhcdFromComboBox.Text)<>'') or (Trim(WhcdFromComboBox.Text)<>'') then
begin
WhcdFrom := trim(WhcdFromComboBox.Text);
WhcdTo := trim(WhcdToComboBox.Text);
if WhcdFromComboBox.ItemIndex>WhcdToComboBox.ItemIndex then
begin
ShowMessage('文化程度设置有问题,请重新检查');
WhcdFromComboBox.SetFocus;
end
else
begin
whcds := '';
for i:=WhcdFRomComboBox.itemindex to WhcdToComboBox.itemindex do begin
whcds:=whcds+','+''+WhcdFRomComboBox.items[i]+'''';
end;
Delete(whcds,1,1);
if SqlStr='' then
SqlStr :='whcd in+whcds'
else
SqlStr := Sqlstr+'and whcd in+whcds';
end;
end;


try
with DataModuleADO.ADOQuery1 do
begin
SQL.Clear;
sql.add(trim(SqlStr));

{cdsnghw提供的SQL语串: sql.add('select * from gugan where now between dateadd(''yyyy'','+AgefromEdit.text+',birthday) and dateadd(''yyyy'','+AgeToEdit.text+',birthday) and now between dateadd(''yyyy'','+RzzFromEdit.text+',Rzz_time) and dateadd(''yyyy'','+RzztoEdit.text+',Rzz_time) and whcd in'+whcds);}

open;
DataSource1.DataSet:=DataModuleADO.ADOQuery1;
DbGrid1.DataSource:=DataSource1;
end;
except
MessageDlg('年龄、文化程度或任正职时间查询有误!',mtError,[mbok],0);
end;

end; //顶层try
except
MessageDlg('查询条件设置存在问题,请检查是否设置正确、完整!',mtError,[mbok],0);
end;

RedAngler 2008-03-20
  • 打赏
  • 举报
回复
我按cdsnghw的思路写了以下程序段,但还是不行,问题出在SQL语串上,请各高手帮我检查检查。
procedure TForm1.BitBtn4Click(Sender: TObject);

var
i,AgeFrom,AgeTo,RzzFrom,RzzTo : integer;
WhcdFrom,WhcdTo,SqlStr,whcds : string;

begin
SqlStr := '';
try
begin

{年龄查询条件处理}
if (Trim(AgeFromEdit.Text)<>'') or (Trim(AgeToEdit.Text)<>'') then
begin
AgeFrom := StrToInt(trim(AgeFromEdit.Text));
AgeTo := StrToInt(trim(AgeToEdit.Text));
if AgeFrom>AgeTo then
begin
ShowMessage('年龄设置有问题,请重新检查');
AgeFromEdit.SetFocus;
end
else if SqlStr='' then
SqlStr := 'now between dateadd(''yyyy'','+AgefromEdit.text+',birthday) and dateadd(''yyyy'','+AgeToEdit.text+',birthday)'
else
SqlStr := SqlStr+'and now between dateadd(''yyyy'','+AgefromEdit.text+',birthday) and dateadd(''yyyy'','+AgeToEdit.text+',birthday)';
end;

{任正职时间查询条件处理}
if (Trim(RzzFromEdit.Text)<>'') or (Trim(RzzToEdit.Text)<>'') then
begin
RzzFrom := StrToInt(trim(RzzFromEdit.Text));
RzzTo := StrToInt(trim(RzzToEdit.Text));
if RzzFrom>RzzTo then
begin
ShowMessage('查询条件<任职时间>设置有问题,请重新检查');
RzzFromEdit.SetFocus;
end
else
begin
if SqlStr='' then
SqlStr :='dateadd(''yyyy'','+RzztoEdit.text+',Rzz_time)'
else
SqlStr := Sqlstr+'and dateadd(''yyyy'','+RzztoEdit.text+',Rzz_time)';
end;
end;

{文化程度查询条件处理}
if (Trim(WhcdFromComboBox.Text)<>'') or (Trim(WhcdFromComboBox.Text)<>'') then
begin
WhcdFrom := trim(WhcdFromComboBox.Text);
WhcdTo := trim(WhcdToComboBox.Text);
if WhcdFromComboBox.ItemIndex>WhcdToComboBox.ItemIndex then
begin
ShowMessage('文化程度设置有问题,请重新检查');
WhcdFromComboBox.SetFocus;
end
else
begin
whcds := '';
for i:=WhcdFRomComboBox.itemindex to WhcdToComboBox.itemindex do begin
whcds:=whcds+','+''+WhcdFRomComboBox.items[i]+'''';
end;
Delete(whcds,1,1);
if SqlStr='' then
SqlStr :='whcd in+whcds'
else
SqlStr := Sqlstr+'and whcd in+whcds';
end;
end;


try
with DataModuleADO.ADOQuery1 do
begin
SQL.Clear;
sql.add(trim(SqlStr));

{cdsnghw提供的SQL语串: sql.add('select * from gugan where now between dateadd(''yyyy'','+AgefromEdit.text+',birthday) and dateadd(''yyyy'','+AgeToEdit.text+',birthday) and now between dateadd(''yyyy'','+RzzFromEdit.text+',Rzz_time) and dateadd(''yyyy'','+RzztoEdit.text+',Rzz_time) and whcd in'+whcds);}

open;
DataSource1.DataSet:=DataModuleADO.ADOQuery1;
DbGrid1.DataSource:=DataSource1;
end;
except
MessageDlg('年龄、文化程度或任正职时间查询有误!',mtError,[mbok],0);
end;

end; //顶层try
except
MessageDlg('查询条件设置存在问题,请检查是否设置正确、完整!',mtError,[mbok],0);
end;

cdsnghw 2008-03-07
  • 打赏
  • 举报
回复

query.sql.add('select * from gugan where now between dateadd(''yyyy'','+nAgefromEdit.text+',birthday) and dateadd(''yyyy'','+nAgeToEdit.text+',birthday) and now between dateadd(''yyyy'','+RzzFromEdit.text+',Rzz_time) and dateadd(''yyyy'','+RzztoEdit.text+',Rzz_time) and whcd in'+whcds);
cdsnghw 2008-03-07
  • 打赏
  • 举报
回复
test
cdsnghw 2008-03-07
  • 打赏
  • 举报
回复
test
cdsnghw 2008-03-07
  • 打赏
  • 举报
回复
for i:=WhcdFRomComboBox.itemindex to WhcdToComboBox.itemindex do begin[更正]
cdsnghw 2008-03-07
  • 打赏
  • 举报
回复
delphi:

var
i:integer;
whcds:string;
begin
whcds:='';
for i:=WhcdFRomComboBox.itemindex to WhcdFRomComboBox.itemindex do begin
whcds:=whcd+','''+WhcdFRomComboBox.items[i]+'''';
end;
delete(whcds,1,1);
whcds:='('+whcds+')';
query1.sql.clear;

query.sql.add('select * from gugan where now between dateadd(''yyyy'','+nAgefromEdit.text+',birthday) and dateadd(''yyyy'','+nAgeToEdit.text+',birthday) and now between dateadd(''yyyy'','+RzzFromEdit.text+',birthday) and dateadd(''yyyy'','+RzztoEdit.text+',birthday) and and whcd in'+whcds);
....


end;
cdsnghw 2008-03-07
  • 打赏
  • 举报
回复
select * from gugan where now between dateadd('yyyy',nAgeFromEdit.text,birthday) and dateadd('yyyy',nAgeFromEdit.text,birthday) and now between dateadd('yyyy',RzzFromEdit.text,birthday) and dateadd('yyyy',RzzFromEdit.text,birthday) and whcd='''+combobox1.text+'''';

i.e.


select * from gugan where now between dateadd('yyyy',40,birthday) and dateadd('yyyy',50,birthday) and now between dateadd('yyyy',3,birthday) and dateadd('yyyy',8,birthday) and whcd='本科';

由于使用了dateadd函数,可以不考虑闰年了

wgej55 2008-03-06
  • 打赏
  • 举报
回复
先定义一个变量,取出当前的时间
var sj:string;
sj:=formatdatetime('yyyymmdd',now);
select * from gugan where (strtoint(sj)-strtoint(convert(birthday,112))) between 40 and 50 and whcd in ('中专','大专','本科') and Rzz_time between 3 and 10

基本的语句就这样,但我不清楚access里面有没有convert函数转换时间,我用的sql数据库,你可以去自己查下看。
RedAngler 2008-03-06
  • 打赏
  • 举报
回复
我是用ADO连接数据库的,请回答的朋友注意提供的SQL语句能直接在AdoQuery1.SQL.add('select * from gugan where xxxxx');正常执行,问题解决立即结贴送分,在线等...
RedAngler 2008-03-06
  • 打赏
  • 举报
回复
更正一下:
(4):WhcdToComboBox(ComboBox供用户选择)
RedAngler 2008-03-06
  • 打赏
  • 举报
回复
这是一个查询界面的要求,查询截面具体为这样:
年龄:_(1)_岁至_(2)__岁 文化程度:_(3)__ 至 __(4)__

任正职时间:_(5)_年至 __(6)__年

对以上这几个数字解释一下:
(1):nAgeFromEdit(文本框供用户输入)
(2):nAgeToEdit(文本框供用户输入)
(3):WhcdFRomComboBox(ComboBox供用户选择)
(4):WhcdFromComboBox(ComboBox供用户选择)
(5):RzzFromEdit(文本框供用户输入)
(6):RzzToEDit(文本框供用户输入)

另外一点就是表中的Whcd(文化程度)为字符型(数据输入界面ComboBox将文化程度对应的字符填入该字段,但为了用户输入和查询数据的方便,将所有学历通过ComboBox提供出来供用户选择)。

这样已经够清楚了吧?请回答问题的朋友仔细考虑下问题的需求,2楼的答案是无法满足需求的,因为文化程度从什么到什么是要用户选择后才能决定的。
cdsnghw 2008-03-06
  • 打赏
  • 举报
回复

.另外不知道虚岁,实岁,闰月有没有对x年产生影响?
虚岁
year(now)-year(birthday) between;
实际岁数很复杂 year(now-birthday)仅仅是近似
(now-birthday)/365.2425也仅仅是近似

哈哈



cdsnghw 2008-03-06
  • 打赏
  • 举报
回复
oracle sql的

你所说的界面指的是数据录入界面而不是报表查询界面吧,所以跟问题没有关系.
如果是查询界面,显然ComboBox不对,因为它是单选的。
你忘记交代文化程度数据类型了,假设是数字类型,0代表小学,1中学

select * from gugan where now-birthday between 40 and 50 and now-Rzz_time between 3 and 8 and whcd between 3 and 5;


假设是字符串类型
select * from gugan where now-birthday between 40 and 50 and now-Rzz_time between 3 and 8 and whcd in ('中专','大专','本科');

如果是单选的combobox1[字符串类型]
那么假设你用delphi
sql.text:='select * from gugan where now-birthday between 40 and 50 and now-Rzz_time between 3 and 8 and whcd='''+combobox1.text+''''

如果是单选的combobox1[数字类型]
那么假设你用delphi
sql.text:='select * from gugan where now-birthday between 40 and 50 and now-Rzz_time between 3 and 8 and whcd='+inttostr(combobox1.itemindex);

2,497

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧