一个连接两个表查询的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)