求设计思路

snlixing 2017-10-13 05:03:44
产量统计按桶统计

2017-10-12早班
桶号 A B C
总重 10kg 15kg 20kg

2017-10-12晚班
桶号 A B D E F
总重 20kg 30kg 20kg 10kg 10kg

2017-10-13早班
桶号 D E F
总重 40kg 30kg 20kg



数据表设计:
日期 班次 桶号 总重 桶重
2017-10-12 早班 A ,B ,C 10,15,20 5,5,2
2017-10-12 晚班 A , B , D, E, F 20,30,20,10,10 5,5,3,3,3
2017-10-13 早班 B, C , D 50,30,40 5,2,3

怎么方便的求出第二个班的产量,就是第二个班的相同桶号的减掉第一个班的




...全文
535 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
吉普赛的歌 版主 2017-10-14
  • 打赏
  • 举报
回复
USE tempdb
GO
IF OBJECT_ID('bucket_data') IS NOT NULL DROP TABLE bucket_data
IF OBJECT_ID('schedule_data') IS NOT NULL DROP TABLE schedule_data
IF OBJECT_ID('schedule_bucket_mid') IS NOT NULL DROP TABLE schedule_bucket_mid
--1. 桶表
CREATE TABLE bucket_data (
	bucketNO VARCHAR(2) NOT NULL PRIMARY KEY,	--桶号
	bucketWeight INT NOT NULL			--桶重
)
--2. 班次表
CREATE TABLE schedule_data (
	scheduleId INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
	currDate DATETIME NOT NULL,		--当前日期
	flag INT NOT NULL				--班次 早班1,晚班2
)
GO
CREATE UNIQUE NONCLUSTERED INDEX IX_schedule_data_currDate_flag ON schedule_data(currDate,flag)

--3. 班次桶中间表
CREATE TABLE schedule_bucket_mid (
	id INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
	scheduleId INT NOT NULL,		--班次ID
	bucketNO VARCHAR(2) NOT NULL,	--桶号
	weight INT NOT NULL				--总重
)

------- 插入测试数据
SET NOCOUNT ON
INSERT INTO bucket_data VALUES('A',5)
INSERT INTO bucket_data VALUES('B',5)
INSERT INTO bucket_data VALUES('C',2)
INSERT INTO bucket_data VALUES('D',3)
INSERT INTO bucket_data VALUES('E',3)
INSERT INTO bucket_data VALUES('F',2)

INSERT INTO schedule_data(currDate,flag) VALUES('2017-10-12', 1)
INSERT INTO schedule_data(currDate,flag) VALUES('2017-10-12', 2)
INSERT INTO schedule_data(currDate,flag) VALUES('2017-10-13', 1)

INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(1,'A',10)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(1,'B',15)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(1,'C',20)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(2,'A',20)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(2,'B',30)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(2,'D',20)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(2,'E',10)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(2,'F',10)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(3,'B',50)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(3,'C',30)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(3,'D',40)

--结果视图1
IF OBJECT_ID('view_result') IS NOT NULL DROP VIEW view_result
GO
CREATE VIEW view_result
AS
SELECT a.currDate AS [日期]
	,CASE a.flag WHEN 1 THEN '早班' WHEN 2 then '晚班' END AS [班次]
	,STUFF( (SELECT ','+b.bucketNO 
			 FROM schedule_bucket_mid AS B WHERE b.scheduleId=a.scheduleId FOR XML PATH('')),1,1,'' ) AS [桶号]
	,STUFF( (SELECT ','+CAST(b.[weight] AS VARCHAR(50)) 
			 FROM schedule_bucket_mid AS B WHERE b.scheduleId=a.scheduleId FOR XML PATH('')),1,1,'' ) AS [总重]
	,STUFF( (SELECT ','+CAST(c.bucketWeight AS VARCHAR(50)) 
			 FROM schedule_bucket_mid AS B INNER JOIN bucket_data AS c ON b.bucketNO=c.bucketNO 
			 WHERE b.scheduleId=a.scheduleId FOR XML PATH('')),1,1,'' ) AS [桶重]
	FROM schedule_data AS A
GO
--SELECT * FROM view_result
/*
日期                      班次   桶号        总重                 桶重
----------------------- ---- ----------   ------------------  -------------
2017-10-12         早班   A,B,C         10,15,20           5,5,2
2017-10-12         晚班   A,B,D,E,F     20,30,20,10,10     5,5,3,3,2
2017-10-13         早班   B,C,D         50,30,40           5,2,3
*/

--结果视图2
--每天最后班次的实际产量
IF OBJECT_ID('view_result2') IS NOT NULL DROP VIEW view_result2
GO
CREATE VIEW view_result2
AS
WITH cte AS (
SELECT a.scheduleId,a.currDate,a.flag,b.bucketNO,b.[weight]
FROM schedule_data A INNER JOIN schedule_bucket_mid AS B ON a.scheduleId=b.scheduleId
)
,cte2 AS (
	SELECT * FROM cte A WHERE NOT EXISTS (
		SELECT 1 FROM cte B WHERE a.currDate=b.currDate AND a.flag<b.flag
	)
)
,cte3 AS(
SELECT  a.currDate,a.flag,a.bucketNO,a.[weight]-ISNULL((
	SELECT sum(b.[weight]) FROM cte AS b WHERE a.currDate=b.currDate AND a.bucketNO=b.bucketNO AND a.flag>b.flag
),0) AS [weight]
FROM cte2 A
)
SELECT a.currDate AS [日期]
,CASE a.flag WHEN 1 THEN '早班' WHEN 2 then '晚班' END AS [班次]
,STUFF(( SELECT ','+b.bucketNO FROM cte3 b WHERE a.currDate=b.currDate AND a.flag=b.flag FOR XML PATH('') ),1,1,'') AS [桶号]
,STUFF(( SELECT ','+CAST(b.[weight] AS VARCHAR(50)) FROM cte3 b WHERE a.currDate=b.currDate AND a.flag=b.flag FOR XML PATH('') ),1,1,'') AS [总重]
,STUFF(( SELECT ','+CAST(c.bucketWeight AS VARCHAR(50)) FROM cte3 b INNER JOIN bucket_data AS c ON c.bucketNO=b.bucketNO 
         WHERE a.currDate=b.currDate AND a.flag=b.flag FOR XML PATH('') ),1,1,'') AS [桶重]
FROM cte3 AS a
WHERE a.[weight]>0
GROUP BY a.currDate,a.flag
GO

SELECT * FROM view_result2
/*
日期                      班次   桶号        总重                 桶重
----------------------- ---- ----------   ------------------  -------------
2017-10-12         晚班   A,B,D,E,F     10,15,20,10,10     5,5,3,3,2
2017-10-13         早班   B,C,D         50,30,40           5,2,3
*/
“第二个班”我理解的是当天最后一个班的产量。 如果你的需求仅仅是晚班的, 稍改一下就可以了。 基本思路就是这样吧。
  • 打赏
  • 举报
回复
tablename(日期,班次,桶号, 总重,桶重)
snlixing 2017-10-14
  • 打赏
  • 举报
回复
引用 5 楼 ayalicer 的回复:
这表设计的像最终报表 但是不利于数据分析
那应该如何设计才好呢
snlixing 2017-10-14
  • 打赏
  • 举报
回复
引用 3 楼 yenange 的回复:
你要的结果, 其实更适合用视图表达, 或者用存储过程生成的结果表, 而不是一个直接设计这么一个表。 良药苦口, 但愿你能明白我的一番苦心。
大师,用视图怎么设计呢
  • 打赏
  • 举报
回复
这表设计的像最终报表 但是不利于数据分析
吉普赛的歌 版主 2017-10-14
  • 打赏
  • 举报
回复
USE tempdb
GO
IF OBJECT_ID('bucket_data') IS NOT NULL DROP TABLE bucket_data
IF OBJECT_ID('schedule_data') IS NOT NULL DROP TABLE schedule_data
IF OBJECT_ID('schedule_bucket_mid') IS NOT NULL DROP TABLE schedule_bucket_mid
--1. 桶表
CREATE TABLE bucket_data (
	bucketNO VARCHAR(2) NOT NULL PRIMARY KEY,	--桶号
	bucketWeight INT NOT NULL			--桶重
)
--2. 班次表
CREATE TABLE schedule_data (
	scheduleId INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
	currDate DATETIME NOT NULL,		--当前日期
	flag INT NOT NULL				--班次 早班1,晚班2
)
GO
CREATE UNIQUE NONCLUSTERED INDEX IX_schedule_data_currDate_flag ON schedule_data(currDate,flag)

--3. 班次桶中间表
CREATE TABLE schedule_bucket_mid (
	id INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
	scheduleId INT NOT NULL,		--班次ID
	bucketNO VARCHAR(2) NOT NULL,	--桶号
	weight INT NOT NULL				--总重
)

------- 插入测试数据
SET NOCOUNT ON
INSERT INTO bucket_data VALUES('A',5)
INSERT INTO bucket_data VALUES('B',5)
INSERT INTO bucket_data VALUES('C',2)
INSERT INTO bucket_data VALUES('D',3)
INSERT INTO bucket_data VALUES('E',3)
INSERT INTO bucket_data VALUES('F',2)

INSERT INTO schedule_data(currDate,flag) VALUES('2017-10-12', 1)
INSERT INTO schedule_data(currDate,flag) VALUES('2017-10-12', 2)
INSERT INTO schedule_data(currDate,flag) VALUES('2017-10-13', 1)

INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(1,'A',10)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(1,'B',15)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(1,'C',20)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(2,'A',20)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(2,'B',30)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(2,'D',20)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(2,'E',10)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(2,'F',10)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(3,'B',50)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(3,'C',30)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(3,'D',40)

--结果视图1
IF OBJECT_ID('view_result') IS NOT NULL DROP VIEW view_result
GO
CREATE VIEW view_result
AS
SELECT a.currDate AS [日期]
	,CASE a.flag WHEN 1 THEN '早班' WHEN 2 then '晚班' END AS [班次]
	,STUFF( (SELECT ','+b.bucketNO 
			 FROM schedule_bucket_mid AS B WHERE b.scheduleId=a.scheduleId FOR XML PATH('')),1,1,'' ) AS [桶号]
	,STUFF( (SELECT ','+CAST(b.[weight] AS VARCHAR(50)) 
			 FROM schedule_bucket_mid AS B WHERE b.scheduleId=a.scheduleId FOR XML PATH('')),1,1,'' ) AS [总重]
	,STUFF( (SELECT ','+CAST(c.bucketWeight AS VARCHAR(50)) 
			 FROM schedule_bucket_mid AS B INNER JOIN bucket_data AS c ON b.bucketNO=c.bucketNO 
			 WHERE b.scheduleId=a.scheduleId FOR XML PATH('')),1,1,'' ) AS [桶重]
	FROM schedule_data AS A
GO
--结果视图2
--每个班次的实际产量
IF OBJECT_ID('view_result2') IS NOT NULL DROP VIEW view_result2
GO
CREATE VIEW view_result2
AS
WITH cte AS (
SELECT ROW_NUMBER() OVER (PARTITION BY b.bucketNO ORDER BY a.currDate,a.flag) AS rid
,a.scheduleId
,a.currDate
,a.flag
,b.bucketNO
,b.[weight]
FROM schedule_data A INNER JOIN schedule_bucket_mid AS B ON a.scheduleId=b.scheduleId
)
,cte2 AS(
SELECT a.scheduleId,a.currDate,a.flag,a.bucketNO,a.[weight]-ISNULL((
	SELECT b.[weight] FROM cte AS b WHERE a.rid=b.rid+1 AND a.bucketNO=b.bucketNO
),0) AS [weight]
FROM cte A
)
SELECT a.currDate AS [日期]
,CASE a.flag WHEN 1 THEN '早班' WHEN 2 then '晚班' END AS [班次]
,STUFF(( SELECT ','+b.bucketNO FROM cte2 b WHERE a.scheduleId=b.scheduleId FOR XML PATH('') ),1,1,'') AS [桶号]
,STUFF(( SELECT ','+CAST(b.[weight] AS VARCHAR(50)) FROM cte2 b WHERE a.scheduleId=b.scheduleId FOR XML PATH('') ),1,1,'') AS [实际产量]
,STUFF(( SELECT ','+CAST(c.bucketWeight AS VARCHAR(50)) FROM cte2 b INNER JOIN bucket_data AS c ON c.bucketNO=b.bucketNO 
         WHERE a.currDate=b.currDate AND a.flag=b.flag FOR XML PATH('') ),1,1,'') AS [桶重]
FROM schedule_data AS a
GO

SELECT * FROM view_result
/*
日期                    班次   桶号        总重                 桶重
----------------------- ---- ----------   ------------------  -------------
2017-10-12              早班   A,B,C         10,15,20           5,5,2
2017-10-12              晚班   A,B,D,E,F     20,30   ,20,10,10  5,5,3,3,2
2017-10-13              早班   B,C,D            50,30,40        5,2,3
*/
SELECT * FROM view_result2
/*
日期                    班次   桶号        实际产量             桶重
----------------------- ---- ----------   ------------------  -------------
2017-10-12              早班   A,B,C         10,15,20           5,5,2
2017-10-12              晚班   A,B,D,E,F     10,15,   20,10,10  5,5,3,3,2
2017-10-13              早班   B,C,D            20,10,20        5,2,3
*/
snlixing 2017-10-14
  • 打赏
  • 举报
回复
引用 8 楼 yenange 的回复:
USE tempdb
GO
IF OBJECT_ID('bucket_data') IS NOT NULL DROP TABLE bucket_data
IF OBJECT_ID('schedule_data') IS NOT NULL DROP TABLE schedule_data
IF OBJECT_ID('schedule_bucket_mid') IS NOT NULL DROP TABLE schedule_bucket_mid
--1. 桶表
CREATE TABLE bucket_data (
	bucketNO VARCHAR(2) NOT NULL PRIMARY KEY,	--桶号
	bucketWeight INT NOT NULL			--桶重
)
--2. 班次表
CREATE TABLE schedule_data (
	scheduleId INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
	currDate DATETIME NOT NULL,		--当前日期
	flag INT NOT NULL				--班次 早班1,晚班2
)
GO
CREATE UNIQUE NONCLUSTERED INDEX IX_schedule_data_currDate_flag ON schedule_data(currDate,flag)

--3. 班次桶中间表
CREATE TABLE schedule_bucket_mid (
	id INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
	scheduleId INT NOT NULL,		--班次ID
	bucketNO VARCHAR(2) NOT NULL,	--桶号
	weight INT NOT NULL				--总重
)

------- 插入测试数据
SET NOCOUNT ON
INSERT INTO bucket_data VALUES('A',5)
INSERT INTO bucket_data VALUES('B',5)
INSERT INTO bucket_data VALUES('C',2)
INSERT INTO bucket_data VALUES('D',3)
INSERT INTO bucket_data VALUES('E',3)
INSERT INTO bucket_data VALUES('F',2)

INSERT INTO schedule_data(currDate,flag) VALUES('2017-10-12', 1)
INSERT INTO schedule_data(currDate,flag) VALUES('2017-10-12', 2)
INSERT INTO schedule_data(currDate,flag) VALUES('2017-10-13', 1)

INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(1,'A',10)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(1,'B',15)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(1,'C',20)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(2,'A',20)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(2,'B',30)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(2,'D',20)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(2,'E',10)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(2,'F',10)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(3,'B',50)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(3,'C',30)
INSERT INTO schedule_bucket_mid(scheduleId,	bucketNO,[weight]) VALUES(3,'D',40)

--结果视图1
IF OBJECT_ID('view_result') IS NOT NULL DROP VIEW view_result
GO
CREATE VIEW view_result
AS
SELECT a.currDate AS [日期]
	,CASE a.flag WHEN 1 THEN '早班' WHEN 2 then '晚班' END AS [班次]
	,STUFF( (SELECT ','+b.bucketNO 
			 FROM schedule_bucket_mid AS B WHERE b.scheduleId=a.scheduleId FOR XML PATH('')),1,1,'' ) AS [桶号]
	,STUFF( (SELECT ','+CAST(b.[weight] AS VARCHAR(50)) 
			 FROM schedule_bucket_mid AS B WHERE b.scheduleId=a.scheduleId FOR XML PATH('')),1,1,'' ) AS [总重]
	,STUFF( (SELECT ','+CAST(c.bucketWeight AS VARCHAR(50)) 
			 FROM schedule_bucket_mid AS B INNER JOIN bucket_data AS c ON b.bucketNO=c.bucketNO 
			 WHERE b.scheduleId=a.scheduleId FOR XML PATH('')),1,1,'' ) AS [桶重]
	FROM schedule_data AS A
GO
--SELECT * FROM view_result
/*
日期                      班次   桶号        总重                 桶重
----------------------- ---- ----------   ------------------  -------------
2017-10-12         早班   A,B,C         10,15,20           5,5,2
2017-10-12         晚班   A,B,D,E,F     20,30,20,10,10     5,5,3,3,2
2017-10-13         早班   B,C,D         50,30,40           5,2,3
*/

--结果视图2
--每天最后班次的实际产量
IF OBJECT_ID('view_result2') IS NOT NULL DROP VIEW view_result2
GO
CREATE VIEW view_result2
AS
WITH cte AS (
SELECT a.scheduleId,a.currDate,a.flag,b.bucketNO,b.[weight]
FROM schedule_data A INNER JOIN schedule_bucket_mid AS B ON a.scheduleId=b.scheduleId
)
,cte2 AS (
	SELECT * FROM cte A WHERE NOT EXISTS (
		SELECT 1 FROM cte B WHERE a.currDate=b.currDate AND a.flag<b.flag
	)
)
,cte3 AS(
SELECT  a.currDate,a.flag,a.bucketNO,a.[weight]-ISNULL((
	SELECT sum(b.[weight]) FROM cte AS b WHERE a.currDate=b.currDate AND a.bucketNO=b.bucketNO AND a.flag>b.flag
),0) AS [weight]
FROM cte2 A
)
SELECT a.currDate AS [日期]
,CASE a.flag WHEN 1 THEN '早班' WHEN 2 then '晚班' END AS [班次]
,STUFF(( SELECT ','+b.bucketNO FROM cte3 b WHERE a.currDate=b.currDate AND a.flag=b.flag FOR XML PATH('') ),1,1,'') AS [桶号]
,STUFF(( SELECT ','+CAST(b.[weight] AS VARCHAR(50)) FROM cte3 b WHERE a.currDate=b.currDate AND a.flag=b.flag FOR XML PATH('') ),1,1,'') AS [总重]
,STUFF(( SELECT ','+CAST(c.bucketWeight AS VARCHAR(50)) FROM cte3 b INNER JOIN bucket_data AS c ON c.bucketNO=b.bucketNO 
         WHERE a.currDate=b.currDate AND a.flag=b.flag FOR XML PATH('') ),1,1,'') AS [桶重]
FROM cte3 AS a
WHERE a.[weight]>0
GROUP BY a.currDate,a.flag
GO

SELECT * FROM view_result2
/*
日期                      班次   桶号        总重                 桶重
----------------------- ---- ----------   ------------------  -------------
2017-10-12         晚班   A,B,D,E,F     10,15,20,10,10     5,5,3,3,2
2017-10-13         早班   B,C,D         50,30,40           5,2,3
*/
“第二个班”我理解的是当天最后一个班的产量。 如果你的需求仅仅是晚班的, 稍改一下就可以了。 基本思路就是这样吧。
谢谢大师,第二个班的意思是下一个班,比如 2017-10-12 早班下一个班就是 2017-10-12 晚班,2017-10-12 晚班下一个班就是2017-10-13 早班 而且2017-10-13 早班C桶的量应该减掉2017-10-12 早班C桶的量,B,D桶的量应该减掉2017-10-12 晚班的量,就是说应该减掉上一个对应桶的量
繁花尽流年 2017-10-13
  • 打赏
  • 举报
回复
LZ想表达什么没太明白
吉普赛的歌 版主 2017-10-13
  • 打赏
  • 举报
回复
你要的结果, 其实更适合用视图表达, 或者用存储过程生成的结果表, 而不是一个直接设计这么一个表。 良药苦口, 但愿你能明白我的一番苦心。
吉普赛的歌 版主 2017-10-13
  • 打赏
  • 举报
回复
你的表设计就有问题, 要能实现你的功能, 最好是将表设计的 不含任何逗号 如果你学过数据库设计, 就应该知道三范式, 知道 E-R 图。 当然, 你不按三范式设计, 也能出来结果, 但就比较复杂了。 SQL搞得复杂, 弯路走得多, 表大了效率非常低下。 建议把表分成两个到三个吧, 类似如下: --班次表 班次ID 日期 班次 1 2017-10-12 早班 2 2017-10-12 晚班 3 2017-10-13 早班 --班次详情表 id 班次ID 桶号 总重 桶重 1 1 A 10 5 2 1 B 15 5 ……

34,591

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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