Questions:连接两个表进行查询:可以输入或不输入查询条件的sql 语句

来源:互联网 发布:c语言生成随机数的函数 编辑:程序博客网 时间:2024/05/02 02:05

一个连接两个表查询的sql 语句的思考

A 字段 gn,rq,qnt

数据:

1001  2004-01-01 10

.....

1002 2004-01-04 3

.......

B 字段 gn,rq,qnt

数据:

1001  2004-01-01 3

 ....

1002  2004-01-04 6

......

 

我现在要出来这样的结果:

 a.gn  a.rq     a.qnt  b.rq        b.qnt

 1001  2004-01-01 10    2004-01-01    3

 1002  2004-01-03 3     2004-01-04   6

 

 

关于简单连接语法汇总查询:

1两表数据是一对一关系,只需要两个表都有的部分,用楼上的方法:

select a.gn,a.rq,a.qnt,b.rq,b.qnt from a,b where a.gn=b.gn

2两表是一对一关系,左表比右表数据多,要查所有左表数据与右表数据的连接,右表没数据的用空值补上:

select a.gn,a.rq,a.qnt,b.rq,b.qnt from a,b where a.gn=b.gn(+);

3两表是一对多关系(典型的如主/明细表),查左表(主表)数据与右表(明细表)数据的对应关系:

 

select a.gn,a.rq,a.qnt,聚合函数(b.rq,聚合函数(b.qnt from a,b where a.gn=b.gn group by a.gn,a.rq,a.qnt;

4两表是一对多关系(典型的如主/明细表),查右表(明细)数据与左表(主表)数据的对应关系:

select a.gn,a.rq,a.qnt,b.rq,b.qnt from a,b where a.gn=b.gn

5两表是多对多关系:慎用连接,最好先聚合后用非聚合嵌套查询,总之就是尽量分解成一多或一一关系,否则查询结果集会几何及数增长;

我知道的就这么多了,大家多交流啊

整个需求是在form 里输入类似


如图的选项
可以输入
1.类别
2.类别+代号
3.类别+日期
4.代号
5.代号+日期
6.日期
7.无任何输入,显示所有

在where 后面我通过提示测试过了
第一种
where (a.部门 = :p_dept or :p_dept is null) 
   and (a.日期 = :p_date or :p_date is null) 
   and (a.类别 = :p_type or :p_type is null) 
第二种
where  nvl2(col, between sdate and  fdate , 1=1 )
可是都会被DB报错误.

不知道大家做项目的时候遇见此类问题是如何写的?

大家有见过把NVL() , DECODE() 函数写到WHERE 后面吗?

 

这样写可以吗

我写了总是在提示"没有结束标记,语句不正确"

 

SELECT fd.department_name, fc.cate_name, fdh.newid, fdh.nfixname, fdh.qty,

       fdh.getdate, fdh.pledge, fdh.getcost, fdh.fixamt, fdh.rcost,

       fdh.depcost, fdh.depyear, fdh.depmon, fdh.yeardep, fdh.deptot,

       fdh.getcost + fdh.fixamt - deptot, fdh.input

  FROM fams_document_heads fdh, fa_cate fc, fams_department fd

 WHERE fc.cate_no = fdh.mainid AND fdh.ndepid = fd.department_no 

    NVL2(&sDate, and fdh.GETDATE between to_date(sDate, 'yyyy-mm-dd') and to_date(&fDate, 'yyyy-mm-dd') , and 1=1 )

 

 

我刚改了一下:

 

SELECT fd.department_name, fc.cate_name, fdh.newid, fdh.nfixname, fdh.qty,

       fdh.getdate, fdh.pledge, fdh.getcost, fdh.fixamt, fdh.rcost,

       fdh.depcost, fdh.depyear, fdh.depmon, fdh.yeardep, fdh.deptot,

       fdh.getcost + fdh.fixamt - deptot, fdh.input

  FROM fams_document_heads fdh, fa_cate fc, fams_department fd

 WHERE fc.cate_no = fdh.mainid AND fdh.ndepid = fd.department_no /*and 1=1*/  

       and  NVL2(&sDate,  fdh.GETDATE between to_date(sDate, 'yyyy-mm-dd') and to_date(&fDate, 'yyyy-mm-dd') ,  1=1 )

 

还是报错:

invalid number of arguments

 

 

nvl只有两个参数,nvl2才有3个参数。你写的and  NVL2(&sDate,  fdh.GETDATE between to_date(sDate, 'yyyy-mm-dd') and to_date(&fDate, 'yyyy-mm-dd') ,  1=1 ) ,返回的结果事boolean变量吗?

 

 

我试了一下知道为什么了,这是因为,nvl2(a,b,c)要求三个参数的类型一样,另外,如果想使用这样的nvl2(a,b,c)函数还要注意,条件一定要写在函数外面,不然会报“不可用的关系运算符”我写了一个简单的例子,你参考改一下吧,呵呵

 

select count(*) from mytest_tab

  where nvl2(col1,'col1','1')=1;

 

这样就没错了,我的col1是字符类型的,如果是日期类型,要自己使用to_date(col_name,'yyyy-mm-dd')进行处理。

 

nvl2()的参数可以为表达式,报错的原因是where子句的问题,where只能是逻辑表达式,nvl2()不是逻辑表达式。

 

最后解决的答案:

 

SELECT fd.department_no, fd.department_name, fc.cate_no, fc.cate_name, fdh.newid, fdh.nfixname, fdh.qty,

       fdh.getdate, fdh.pledge, fdh.getcost, fdh.fixamt, fdh.rcost,

       fdh.depcost, fdh.depyear, fdh.depmon, fdh.yeardep, fdh.deptot,

       fdh.getcost + fdh.fixamt - fdh.deptot, fdh.input

  FROM fams_document_heads fdh, fa_cate fc, fams_department fd

 WHERE fc.cate_no = fdh.mainid

   AND fdh.ndepid = fd.department_no

   AND fdh.getdate >= NVL (:p_fromdate, fdh.getdate)

   AND fdh.getdate <= NVL (:p_todate, fdh.getdate)

   AND fc.cate_no >= NVL (:p_fromcate, fc.cate_no)

   AND fc.cate_no <= NVL (:p_tocate, fc.cate_no)

   AND fd.department_no >= NVL (:p_fromdep, fd.department_no)

   AND fd.department_no <= NVL (:p_todep, fd.department_no)

 

 

原创粉丝点击