sql 语句请教

zestsnake 2018-03-20 11:30:41





有如上图所示的数据表和得到结果

其中 balance 是主表,1年约有1000W的记录 ,已做过分区
今年是2018年,那么就和 2017,2016 比年末的数据
如果是2019年,那么就和 2018,2017 比年末的数据,对比的数据表每年年末会产生,且只保留12.31的数据
...全文
630 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
听雨停了 2018-03-21
  • 打赏
  • 举报
回复
引用 7 楼 zestsnake 的回复:
谢谢 有个疑问,如果这个问题比较低级请见谅 LEFT JOIN balance AS b ON a.balance_account=b.balance_account AND a.balance_date=DATEADD(DAY,1,b.balance_date) LEFT JOIN balance AS c ON a.balance_account=c.balance_account AND c.balance_date=DATEADD(MONTH,DATEDIFF(MONTH,'19991231',@dt)-1,'19991231') 这里,连续join 同一张1000W级数据的表,效率会不会低?
这个问题你可以自己试一下就知道了,你的表结构什么的我也不知道,具体情况也不好说。如果你觉得慢的话你这里可以不使用left join,直接把三个结果(今日,比昨日,比上月末)单独查询出来再去做关联
zestsnake 2018-03-20
  • 打赏
  • 举报
回复

这里错了
1111 这个账号应该是
今日 比昨日 比上月末 比2017 比2016
100 30(100-70) -390 (100-490) 95(100-5) 40(100-60)

说明下,如果今天是 3月9日 ,那么就 要和 3月8日 ,2.28日比较下 (还得考虑下闰年)
zestsnake 2018-03-20
  • 打赏
  • 举报
回复
谢谢 有个疑问,如果这个问题比较低级请见谅 LEFT JOIN balance AS b ON a.balance_account=b.balance_account AND a.balance_date=DATEADD(DAY,1,b.balance_date) LEFT JOIN balance AS c ON a.balance_account=c.balance_account AND c.balance_date=DATEADD(MONTH,DATEDIFF(MONTH,'19991231',@dt)-1,'19991231') 这里,连续join 同一张1000W级数据的表,效率会不会低?
听雨停了 2018-03-20
  • 打赏
  • 举报
回复
引用 5 楼 zestsnake 的回复:
[quote=引用 4 楼 yenange 的回复:]
[quote=引用 2 楼 qq_37170555 的回复:]
最好把测试数据以文本的方式发出来,不要发图片。这样可以更方便别人帮你写sql

雨亭V5 [/quote]

啊能帮我想想看 [/quote]
你最后发出来的结果应该还是有点问题的,根据你提供的测试数据,最后的结果应该是这样的

if not object_id(N'balance') is null
drop table balance
Go
Create table balance([balance_id] int,[balance_account] int,[balance_name] nvarchar(21),[balance_df] int,[balance_date] Date)
Insert balance
select 1,1234,N'a',15,'2018/1/1' union all
select 2,1234,N'a',20,'2018/1/31' union all
select 3,1234,N'a',30,'2018/2/5' union all
select 4,1234,N'a',40,'2018/2/6' union all
select 5,1111,N'b',30,'2018/1/1' union all
select 6,1111,N'b',490,'2018/1/31' union all
select 7,1111,N'b',70,'2018/2/5' union all
select 8,1111,N'b',100,'2018/2/6'
Go
if not object_id(N'balance2016') is null
drop table balance2016
Go
Create table balance2016([balance_id] int,[balance_account] int,[balance_name] nvarchar(21),[balance_df] int,[balance_date] Date)
Insert balance2016
select 1,1234,N'a',10,'2016/12/31' union all
select 2,1111,N'b',5,'2016/12/31'
Go
if not object_id(N'balance2017') is null
drop table balance2017
Go
Create table balance2017([balance_id] int,[balance_account] int,[balance_name] nvarchar(21),[balance_df] int,[balance_date] Date)
Insert balance2017
select 1,1234,N'a',100,'2017/12/31' union all
select 2,1111,N'b',60,'2017/12/31'
Go
--测试数据结束


DECLARE @dt DATE,--当前日期
@year INT,--今年的年份
@tabName1 VARCHAR(20),--去年的表名称
@tabName2 VARCHAR(20),--前年的表名称
@sql VARCHAR(max)
SET @dt='2018-02-06'--设置当前日期"GetDate()"
SET @year=DATEPART(YEAR,@dt)--得到当前年份
SET @tabName1='balance'+CAST(@year-1 AS VARCHAR(20))--得到去年的表名称
SET @tabName2='balance'+CAST(@year-2 AS VARCHAR(20))--得到前年的表名称

--查询今日,比昨日,比上月末的数据插入临时表#tab中
IF NOT OBJECT_ID('tempdb..#tab') IS NULL
DROP TABLE #tab
SELECT a.balance_account,a.balance_name,a.balance_df AS '今日',a.balance_df-b.balance_df AS '比昨日',a.balance_df-c.balance_df as '比上月末'
INTO #tab
FROM balance AS a
LEFT JOIN balance AS b ON a.balance_account=b.balance_account AND a.balance_date=DATEADD(DAY,1,b.balance_date)
LEFT JOIN balance AS c ON a.balance_account=c.balance_account AND c.balance_date=DATEADD(MONTH,DATEDIFF(MONTH,'19991231',@dt)-1,'19991231')
WHERE a.balance_date=@dt

--判断去年/前年的表是否存在
IF OBJECT_ID(@tabName1) IS NULL
BEGIN
PRINT @tabName1+'表不存在!'
RETURN
END
Else IF OBJECT_ID(@tabName2) IS NULL
BEGIN
PRINT @tabName2+'表不存在!'
RETURN
END
ELSE
SET @sql='select a.*,a.今日-b.balance_df as ''比'+cast(@year-1 as varchar)+ ''',a.今日-c.balance_df as ''比'+cast(@year-2 as varchar)+''' from #tab as a
left join '+@tabName1+' as b on a.balance_account=b.balance_account
left join '+@tabName2+' as c on a.balance_account=c.balance_account'

--执行拼接的SQL语句得到最后的结果
EXEC (@sql)

zestsnake 2018-03-20
  • 打赏
  • 举报
回复
引用 4 楼 yenange 的回复:
[quote=引用 2 楼 qq_37170555 的回复:] 最好把测试数据以文本的方式发出来,不要发图片。这样可以更方便别人帮你写sql
雨亭V5 [/quote] 啊能帮我想想看
吉普赛的歌 2018-03-20
  • 打赏
  • 举报
回复
引用 2 楼 qq_37170555 的回复:
最好把测试数据以文本的方式发出来,不要发图片。这样可以更方便别人帮你写sql
雨亭V5
zestsnake 2018-03-20
  • 打赏
  • 举报
回复
balance 主表 balance_id 自动编号 balance_account 账号 balance_name 户名 balance_df 金额 balance_date 日期 测试数据 balance_id balance_account balance_name balance_df balance_date 1 1234 a 15 2018/1/1 2 1234 a 20 2018/1/31 3 1234 a 30 2018/2/5 4 1234 a 40 2018/2/6 5 1111 b 30 2018/1/1 6 1111 b 490 2018/1/31 7 1111 b 70 2018/2/5 8 1111 b 100 2018/2/6 balance2016 2017年 balance_id 自动编号 balance_account 账号 balance_name 户名 balance_df 金额 balance_date 日期 测试数据 balance_id balance_account balance_name balance_df balance_date 1 1234 a 10 2016/12/31 2 1111 b 5 2016/12/31 balance2017 2016年 balance_id 自动编号 balance_account 账号 balance_name 户名 balance_df 金额 balance_date 日期 测试数据 balance_id balance_account balance_name balance_df balance_date 1 1234 a 100 2017/12/31 2 1111 b 60 2017/12/31 得到结果是 如果今天是2月6日 balance_account balance_name 今日 比昨日 比上 月末 比2017 比2016 1234 a 40 10(40-30) 20(40-20) -10(40-50) -60(40-100) 1111 b 100 30(100-70) -390(100-490) 95(100-5) 40(100-60)
听雨停了 2018-03-20
  • 打赏
  • 举报
回复
最好把测试数据以文本的方式发出来,不要发图片。这样可以更方便别人帮你写sql

11,848

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 非技术版
社区管理员
  • 非技术版社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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