求一复杂SQL语句

custom1234 2014-11-17 01:22:46
先上图 :


如图上所示。
以下为数据库数据:
姓名	卡号		账单日	还款日	固定额度	还款类型	还款金额	还款日期
王五 52245678920 6 25 50000 计划 1000 2014/11/12
王五 42113652489 9 20 20000 实际 2300 2014/11/10
张三 12345678911 12 28 25000 实际 200 2014/11/13
张三 12345678911 12 28 25000 计划 150 2014/11/10


日期是最早账单日到最晚账单日之间的这段日期,如:上面的数据中:6号的账单日最小,28号的账单日最大,所以
日期就是6到28这段日期!

如果sql语句能兼容sqlite就更好。
...全文
397 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
custom1234 2014-11-17
  • 打赏
  • 举报
回复
引用 14 楼 ky_min 的回复:
DECLARE @MinDate DATETIME,@MaxDate DATETIME
SELECT @MinDate=MIN(CAST(CONVERT(VARCHAR(8),还款日期,111)+CAST(账单日 AS VARCHAR(10))AS DATETIME))
	,@MaxDate=MAX(CAST(CONVERT(VARCHAR(8),还款日期,111)+CAST(还款日 AS VARCHAR(10))AS DATETIME))
FROM 表名
DECLARE @SQL VARCHAR(MAX)
SET @SQL=''
DECLARE @SQL2 VARCHAR(MAX)
SET @SQL2=''
SELECT @SQL=@SQL+',SUM(CASE WHEN CONVERT(VARCHAR(10),还款日期,111)='''+CONVERT(VARCHAR(10),DATEADD(DAY,number,@MinDate),111)
			+''' THEN 还款金额 END)['+CONVERT(VARCHAR(10),DATEADD(DAY,number,@MinDate),111)+']'
	,@SQL2=@SQL2+',NULL ['+CONVERT(VARCHAR(10),DATEADD(DAY,number,@MinDate),111)+']'
FROM master..spt_values
WHERE type='P'AND number<=DATEDIFF(DAY,@MinDate,@MaxDate)
SET @SQL='SELECT 姓名,卡号,还款类型[项目],SUM(还款金额)[合计]'+@SQL+',1[A]FROM 表名 GROUP BY 姓名,卡号,还款类型'
		+' UNION ALL '
		+'SELECT 姓名,卡号,''固定额度'',固定额度'+@SQL2+',2[A]FROM 表名 GROUP BY 姓名,卡号,固定额度'
		+' ORDER BY 姓名,卡号,A'
EXEC(@SQL)
小调下
太感谢了!ky_min !!
还在加载中灬 2014-11-17
  • 打赏
  • 举报
回复
DECLARE @MinDate DATETIME,@MaxDate DATETIME
SELECT @MinDate=MIN(CAST(CONVERT(VARCHAR(8),还款日期,111)+CAST(账单日 AS VARCHAR(10))AS DATETIME))
	,@MaxDate=MAX(CAST(CONVERT(VARCHAR(8),还款日期,111)+CAST(还款日 AS VARCHAR(10))AS DATETIME))
FROM 表名
DECLARE @SQL VARCHAR(MAX)
SET @SQL=''
DECLARE @SQL2 VARCHAR(MAX)
SET @SQL2=''
SELECT @SQL=@SQL+',SUM(CASE WHEN CONVERT(VARCHAR(10),还款日期,111)='''+CONVERT(VARCHAR(10),DATEADD(DAY,number,@MinDate),111)
			+''' THEN 还款金额 END)['+CONVERT(VARCHAR(10),DATEADD(DAY,number,@MinDate),111)+']'
	,@SQL2=@SQL2+',NULL ['+CONVERT(VARCHAR(10),DATEADD(DAY,number,@MinDate),111)+']'
FROM master..spt_values
WHERE type='P'AND number<=DATEDIFF(DAY,@MinDate,@MaxDate)
SET @SQL='SELECT 姓名,卡号,还款类型[项目],SUM(还款金额)[合计]'+@SQL+',1[A]FROM 表名 GROUP BY 姓名,卡号,还款类型'
		+' UNION ALL '
		+'SELECT 姓名,卡号,''固定额度'',固定额度'+@SQL2+',2[A]FROM 表名 GROUP BY 姓名,卡号,固定额度'
		+' ORDER BY 姓名,卡号,A'
EXEC(@SQL)
小调下
还在加载中灬 2014-11-17
  • 打赏
  • 举报
回复
不确定兼容LITE,你参考下
DECLARE @MinDate DATETIME,@MaxDate DATETIME
SELECT @MinDate=MIN(CAST(CONVERT(VARCHAR(8),还款日期,111)+CAST(账单日 AS VARCHAR(10))AS DATETIME))
	,@MaxDate=MAX(CAST(CONVERT(VARCHAR(8),还款日期,111)+CAST(还款日 AS VARCHAR(10))AS DATETIME))
FROM 表名
PRINT @MinDate
PRINT @MaxDate
DECLARE @SQL VARCHAR(MAX)
SET @SQL=''
DECLARE @SQL2 VARCHAR(MAX)
SET @SQL2=''
SELECT @SQL=@SQL+',SUM(CASE WHEN CONVERT(VARCHAR(10),还款日期,111)='''+CONVERT(VARCHAR(10),DATEADD(DAY,number,@MinDate),111)
			+''' THEN 还款金额 END)['+CONVERT(VARCHAR(10),DATEADD(DAY,number,@MinDate),111)+']'
	,@SQL2=@SQL2+',NULL ['+CONVERT(VARCHAR(10),DATEADD(DAY,number,@MinDate),111)+']'
FROM master..spt_values
WHERE type='P'AND number<=DATEDIFF(DAY,@MinDate,@MaxDate)
SET @SQL='SELECT 姓名,卡号,还款类型[项目],SUM(还款金额)[合计]'+@SQL+',固定额度,1[A]FROM 表名 GROUP BY 姓名,卡号,还款类型,固定额度'
		+' UNION ALL '
		+'SELECT 姓名,卡号,''固定额度'',固定额度'+@SQL2+',固定额度,2[A]FROM 表名 GROUP BY 姓名,卡号,固定额度'
		+' ORDER BY 姓名,固定额度 DESC,A'
EXEC(@SQL)
还在加载中灬 2014-11-17
  • 打赏
  • 举报
回复
引用 11 楼 custom1234 的回复:
[quote=引用 10 楼 ky_min 的回复:] 以前做FASTREPORT,也是实现过这种类似的,那是交叉报表 其实也是行转列,对于空白的日期列,需要确保有一条数据,行转列出来才能达到效果 可以在程序上处理,也可以在SQL上处理 话说,那些账单日,还款日的年月怎么确定,有可能跨月吗
你说这个跨月情况,暂时不考虑。考虑的话,那更麻烦了。 有SQL语能实现的话,麻烦给我一些提示或一个大概的实现。[/quote]你这个只是动态行转列处理了,先找出最大最小日期,然后从最小日期行转列到最大日期,就可以了
custom1234 2014-11-17
  • 打赏
  • 举报
回复
引用 10 楼 ky_min 的回复:
以前做FASTREPORT,也是实现过这种类似的,那是交叉报表 其实也是行转列,对于空白的日期列,需要确保有一条数据,行转列出来才能达到效果 可以在程序上处理,也可以在SQL上处理 话说,那些账单日,还款日的年月怎么确定,有可能跨月吗
你说这个跨月情况,暂时不考虑。考虑的话,那更麻烦了。 有SQL语能实现的话,麻烦给我一些提示或一个大概的实现。
还在加载中灬 2014-11-17
  • 打赏
  • 举报
回复
以前做FASTREPORT,也是实现过这种类似的,那是交叉报表 其实也是行转列,对于空白的日期列,需要确保有一条数据,行转列出来才能达到效果 可以在程序上处理,也可以在SQL上处理 话说,那些账单日,还款日的年月怎么确定,有可能跨月吗
custom1234 2014-11-17
  • 打赏
  • 举报
回复
引用 8 楼 Tiger_Zhao 的回复:
这种稀疏的数据用SQL不划算。 行列转换完全可以在程序中进行: 原始数据按姓名、卡号、类型、日期排序; 再新建一个DataTable,不定列按日期范围添加; 循环原始数据,添加到目标DataTable,结果就可以用报表来处理了。
谢谢,我根据你提供的思路试试。
Tiger_Zhao 2014-11-17
  • 打赏
  • 举报
回复
这种稀疏的数据用SQL不划算。
行列转换完全可以在程序中进行:
原始数据按姓名、卡号、类型、日期排序;
再新建一个DataTable,不定列按日期范围添加;
循环原始数据,添加到目标DataTable,结果就可以用报表来处理了。
xdashewan 2014-11-17
  • 打赏
  • 举报
回复
引用 4 楼 custom1234 的回复:
就想出一个截图所示的报表,说明一下:程序是winform+sqlite 的一个业务程序。所以才说兼容sqlite数据库的语句更好。不知道你说的外部程序怎么处理。请给我一个解决问题的方向。
winform就是外部程序,你让我做,我肯定会抽出需要数据,按人名,日期排好序,然后由winform程序来处理报表
custom1234 2014-11-17
  • 打赏
  • 举报
回复
上面的回复打错字了: 曾想过用水晶报表来做,但涉及到行列转换,所以还是想在数据库用sql语句来实现更靠谱一点。当然,有用水晶报表能实现的,请赐教。现在也不局限于兼容sqlite了。能用sql语句实现都行。饥不择食了。。。
custom1234 2014-11-17
  • 打赏
  • 举报
回复
曾想过用水晶报表来做,但涉及到转列转换,所以还是想在数据库用sql语句来实现更靠谱一点。当然,有用水晶报表能实现的,请赐教。现在也不局限于兼容sqlite了。能用sql语句实现都行。饥不择食了。。。。
custom1234 2014-11-17
  • 打赏
  • 举报
回复
就想出一个截图所示的报表,说明一下:程序是winform+sqlite 的一个业务程序。所以才说兼容sqlite数据库的语句更好。不知道你说的外部程序怎么处理。请给我一个解决问题的方向。
xdashewan 2014-11-17
  • 打赏
  • 举报
回复
你都用sqlite了,想必应该有外部程序,为何不放到外部程序处理
custom1234 2014-11-17
  • 打赏
  • 举报
回复
求大牛帮帮忙。。。
custom1234 2014-11-17
  • 打赏
  • 举报
回复
一直都在求类似需求的sql,但都没有很好的解决。行转列、列转行!!!!

22,209

社区成员

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

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