请教一个SQL语句的写法

plutu 2013-11-25 05:46:39
现有一个入库计划表master和实际入库明细表details,一个计划表可以对应多次入库,现要形成一个计划入库量对应实际入库量的统计表,示例数据如下:
create table master(ID int,计划号 varchar(5),计划数量 int)
insert into master values(1,'00001',10)
insert into master values(2,'00002',20)
insert into master values(3,'00003',30)
insert into master values(4,'00004',30)

create table detail(ID int,计划号 varchar(5),入库数量 int,操作员 char(6))
insert into detail values(1,'00001',4,'张三')
insert into detail values(2,'00001',6,'张三')
insert into detail values(3,'00002',10,'张三')
insert into detail values(4,'00002',10,'李四')
insert into detail values(5,'00003',30,'李四')
insert into detail values(6,'00004',10,'张三')
insert into detail values(7,'00004',10,'李四')
要形成的统计结果为:
计划号 计划数量 入库数量 操作员
0001 10 4 张三
6 张三
小计 10 10 ---
0002 20 10 张三
10 李四
小计 20 20 ---
0003 30 30 张三
小计 30 30 ---
0004 30 10 张三
10 李四
小计 30 20 ---
总计 90 80 ---
请问这个SQL语句怎么实现?在SQL Server2000环境
...全文
262 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 1 楼 fredrickhu 的回复:
GROUPING函数.GROUP BY WITH ROLLUP的运用。
顶一个
唐诗三百首 2013-11-26
  • 打赏
  • 举报
回复
SQL2000的方法,

create table [master](ID int,计划号 varchar(5),计划数量 int)
insert into master values(1,'00001',10)
insert into master values(2,'00002',20)
insert into master values(3,'00003',30)
insert into master values(4,'00004',30)

create table detail(ID int,计划号 varchar(5),入库数量 int,操作员 char(6))
insert into detail values(1,'00001',4,'张三')
insert into detail values(2,'00001',6,'张三')
insert into detail values(3,'00002',10,'张三')
insert into detail values(4,'00002',10,'李四')
insert into detail values(5,'00003',30,'李四')
insert into detail values(6,'00004',10,'张三')
insert into detail values(7,'00004',10,'李四')


select case when aid is not null and bid is not null and 
                 not exists(select 1 from detail u where u.计划号=t.计划号 and u.ID<t.bid) then 计划号
            when aid is not null and bid is null then '小计'
            when aid is null and bid is null then '总计' else '' end '计划号',
       case when aid is not null and bid is null then
                 (select top 1 rtrim(计划数量) from [master] u where u.ID=t.aid)
            when aid is null and bid is null then
                 (select rtrim(sum(计划数量)) from [master])     
            when aid is not null and bid is not null and 
                 not exists(select 1 from detail u where u.计划号=t.计划号 and u.ID<t.bid) then rtrim(计划数量)
            else '' end '计划数量',
       sum(入库数量) '入库数量',
       case when aid is not null and bid is not null then max(操作员)
            when aid is null or bid is null then '---' end '操作员'
from
(select a.ID 'aid',b.ID 'bid',a.计划号,a.计划数量,b.入库数量,b.操作员
 from [master] a
 left join detail b on a.计划号=b.计划号) t
group by aid,bid,计划号,计划数量
with rollup
having grouping(计划数量)=0 or grouping(bid)=1

/*
计划号   计划数量     入库数量      操作员
----- ------------ ----------- ------
00001    10           4          张三  
                      6          张三  
小计     10           10          ---   
00002    20          10          张三  
                     10          李四  
小计     20           20          ---   
00003   30           30          李四  
小计     30           30          ---   
00004   30           10          张三  
                     10          李四  
小计     30           20          ---   
总计     90           80          ---   

(12 row(s) affected)
*/
ChinaITOldMan 2013-11-26
  • 打赏
  • 举报
回复
GROUPING函数.GROUP BY WITH ROLLUP的运用。
發糞塗牆 2013-11-26
  • 打赏
  • 举报
回复
--create table [master](ID int,计划号 varchar(5),计划数量 int)
--insert into master values(1,'00001',10)
--insert into master values(2,'00002',20)
--insert into master values(3,'00003',30)
--insert into master values(4,'00004',30)

--create table detail(ID int,计划号 varchar(5),入库数量 int,操作员 char(6))
--insert into detail values(1,'00001',4,'张三')
--insert into detail values(2,'00001',6,'张三')
--insert into detail values(3,'00002',10,'张三')
--insert into detail values(4,'00002',10,'李四')
--insert into detail values(5,'00003',30,'李四')
--insert into detail values(6,'00004',10,'张三')
--insert into detail values(7,'00004',10,'李四')



--SELECT m.ID,m.计划号,m.计划数量,d.入库数量,d.操作员 INTO #t 
--FROM [master] m LEFT JOIN detail d ON d.计划号 = m.计划号
SELECT 计划号,计划数量,入库数量,操作员
FROM
(
select 计划号 AS a计划号,--=case when n1=1 AND n2=1 then 计划号 else null END,
        计划号=case when n1=1 AND n2=1 then 计划号 else null END,
		计划数量=case when  n1=1 AND n2=1 then 计划数量 else null END,入库数量,操作员
from 
(
select *,n1=(select count(*) from #t b where  a.计划号=b.计划号 AND a.计划数量=b.计划数量 AND  b.入库数量<=a.入库数量 AND a.操作员<=b.操作员)
       ,n2=(select count(*) from #t b where a.计划号=b.计划号 AND a.计划数量=b.计划数量  and b.入库数量<=a.入库数量 AND a.操作员<=b.操作员)
from #t a
)t
UNION ALL 
SELECT 计划号 a计划号, '小计' 计划号 ,计划数量,SUM(入库数量)入库数量,'--'AS '操作员'
FROM #t a
GROUP BY 计划号,计划数量)a
ORDER BY a计划号,CASE WHEN ISNUMERIC(计划号)=1 THEN 2 WHEN 计划号 IS NULL THEN 1  ELSE 0 END desc

/*
计划号   计划数量        入库数量        操作员
----- ----------- ----------- ------
00001 10          4           张三  
NULL  NULL        6           张三  
小计    10          10          --
00002 20          10          张三  
NULL  NULL        10          李四  
小计    20          20          --
00003 30          30          李四  
小计    30          30          --
00004 30          10          张三  
NULL  NULL        10          李四  
小计    30          20          --
*/
oreoconansisu 2013-11-26
  • 打赏
  • 举报
回复
引用 7 楼 zywcy100 的回复:
[quote=引用 1 楼 fredrickhu 的回复:] GROUPING函数.GROUP BY WITH ROLLUP的运用。
顶一个[/quote] 再顶一个
plutu 2013-11-25
  • 打赏
  • 举报
回复
谢谢,但感觉有点小复杂,并且结果排序不大对,我感觉应该有更简洁一点的办法,请大家继续
LongRui888 2013-11-25
  • 打赏
  • 举报
回复
呵呵,写的有点复杂:

if OBJECT_ID('tempdb..#temp') is not null
   drop table #temp
   
select m.计划号,
       m.计划数量,
       d.入库数量,
       d.操作员,
       d.id
       into #temp       
from [master] m
left join [detail] d
       on m.计划号 = d.计划号



select case when (select COUNT(*) from #temp t2
                  where t2.计划号 = t1.计划号
                        and t2.id <= t1.id) = 1
                 then t1.计划号
            else null
       end as 计划号,
       
       case when (select COUNT(*) from #temp t2
                  where t2.计划号 = t1.计划号
                        and t2.id <= t1.id) = 1
                 then t1.计划数量
            else null
       end as 计划数量,
       
       入库数量,
       操作员
from #temp t1

union all

select '小计',sum(计划数量) ,(select sum(入库数量) 
                             from [detail] d where m.计划号 = d.计划号),'-'
from [master] m
group by 计划号

union all

select '总计',sum(计划数量),(select sum(入库数量) from [detail] d ),'-'
from [master] m
/*

计划号	计划数量	入库数量	操作员
00001	10	    4	    张三
NULL	NULL	6	    张三
00002	20	    10	    张三
NULL	NULL	10	    李四
00003	30	    30	    李四
00004	30	    10	    张三
NULL	NULL	10	    李四
小计	    10	    10	    -
小计	    20	    20	    -
小计	    30	    30	    -
小计	    30	    20	    -
总计	    90	    80	    -
*/
--小F-- 2013-11-25
  • 打赏
  • 举报
回复
另外你的表名命名为MASTER的话 换过一个比较讲究规范的领导 你要被骂死
--小F-- 2013-11-25
  • 打赏
  • 举报
回复
GROUPING函数.GROUP BY WITH ROLLUP的运用。
代码下载地址: https://pan.quark.cn/s/ee8627e4e6d7 ABAP调试器是一种功能强大的工具,可用于在执行期间对ABAP代码进行检验。除了常规的核心功能(例如逐行运行代码以及检验变量、字段符号和引用的值)之外,它还提供了一些辅助性的特性,能够简化并压缩调试会话的时长。并非所有使用者都熟悉这些辅助特性。SAP ABAP调试器是处理和优化ABAP代码开发与维护工作的核心资源,它配备了多样的功能来协助开发人员在运行状态下进行检验和排除故障。此资源着重阐述了ABAP调试器的一些高级特性,涵盖了深入分析调用堆栈、系统级调试、更新会话调试以及提升调试效率的方法。 1. **深入分析调用堆栈**:除了常规的应用程序调试,开发人员有时需要对调用堆栈的内部层级进行深入调试,特别是在错误出现在异步执行的更新处理或系统级程序时。通过启用**系统级调试**,可以访问通常不公开的系统代码,但这也会导致调用堆栈的显著增加,因此需要审慎操作。 2. **系统级调试**:对于不含业务逻辑的系统级程序,开发人员通常无需进行调试。然而,在特定情形下,例如进行错误追踪时,可能需要进入系统代码。借助调试器的“系统调试启用/禁用”选项,可以赋予对系统程序的调试权限。 3. **更新会话调试**:在处理异步更新任务,例如持久化业务数据时,错误可能发生在更新任务内部。激活**更新会话调试**,在更新任务完成后,调试器将自动启动,展示执行路径。比如,在变更成本中心后,通过输入调试指令 "/h" 启动调试,保存后能够看到更新过程中的错误。 4. **分析调用堆栈**:在进行深入调试时,调用堆栈是至关重要的。通过分析调用堆栈,能够定位到引发问题的具体位置,如在VB_V2_NORMAL...

22,296

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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