问题:
一百个账户各有100$,某个账户某天如有支出则添加一条新记录,记录其余额。一百天后,请输出每天所有账户的余额信息
这个问题的难点在于每个用户在某天可能有多条纪录,也可能一条纪录也没有(不包括第一天)
返回的记录集是一个100天*100个用户的纪录集
网上的思路:
1.创建表并插入测试数据:我们要求username从1-100
CREATE TABLE [dbo].[TABLE2] (
[username] [varchar] (50) NOT NULL , --用户名
[outdate] [datetime] NOT NULL , --日期
[cash] [float] NOT NULL --余额
) ON [PRIMARY
declare @i int
set @i=1
while @i<=100
begin
insert table2 values(convert(varchar(50),@i),'2001-10-1',100)
insert table2 values(convert(varchar(50),@i),'2001-11-1',50)
set @i=@i+1
end
insert table2 values(convert(varchar(50),@i),'2001-10-1',90)
select * from table2 order by outdate,convert(int,username)
2.组合查询语句:
a.我们必须返回一个从第一天开始到100天的纪录集:
如:2001-10-1(这个日期是任意的)到 2002-1-8
由于第一天是任意一天,所以我们需要下面的SQL语句:
select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate
from table2
group by username
order by convert(int,username)
这里的奥妙在于:
convert(int,username)-1(记得我们指定用户名从1-100 :-))
group by username,min(outdate):第一天就可能每个用户有多个纪录。
返回的结果:
outdate
------------------------------------------------------
2001-10-01 00:00:00.000
.........
2002-01-08 00:00:00.000
b.返回一个所有用户名的纪录集:
select distinct username from table2
返回结果:
username
--------------------------------------------------
1
10
100
......
99
c.返回一个100天记录集和100个用户记录集的笛卡尔集合:
select * from
(
select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate
from table2
group by username
order by convert(int,username)
) as A
CROSS join
(
select distinct username from table2
) as B
order by outdate,convert(int,username)
返回结果100*100条纪录:
outdate username
2001-10-01 00:00:00.000 1
......
2002-01-08 00:00:00.000 100
d.返回当前所有用户在数据库的有的纪录:
select outdate,username,min(cash) as cash from table2
group by outdate,username
order by outdate,convert(int,username)
返回纪录:
outdate username cash
2001-10-01 00:00:00.000 1 90
......
2002-01-08 00:00:00.000 100 50
e.将c中返回的笛卡尔集和d中返回的纪录做left join:
select C.outdate,C.username,
D.cash
from
(
select * from
(
select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate
from table2
group by username
order by convert(int,username)
) as A
CROSS join
(
select distinct username from table2
) as B
) as C
left join
(
select outdate,username,min(cash) as cash from table2
group by outdate,username
) as D
on(C.username=D.username and datediff(d,C.outdate,D.outdate)=0)
order by C.outdate,convert(int,C.username)
注意:用户在当天如果没有纪录,cash字段返回NULL,否则cash返回每个用户当天的余额
outdate username cash
2001-10-01 00:00:00.000 1 90
2001-10-01 00:00:00.000 2 100
......
2001-10-02 00:00:00.000 1 90
2001-10-02 00:00:00.000 2 NULL <--注意这里
......
2002-01-08 00:00:00.000 100 50
f.好了,现在我们最后要做的就是,如果cash为NULL,我们要返回小于当前纪录日期的第一个用户余额(由于我们使用order by cash,所以返回top 1纪录即可,使用min应该也可以),这个余额即为当前的余额:
case isnull(D.cash,0)
when 0 then
(
select top 1 cash from table2 where table2.username=C.username
and datediff(d,C.outdate,table2.outdate)<0
order by table2.cash
)
else D.cash
end as cash
g.最后组合的完整语句就是
select C.outdate,C.username,
case isnull(D.cash,0)
when 0 then
(
select top 1 cash from table2 where table2.username=C.username
and datediff(d,C.outdate,table2.outdate)<0
order by table2.cash
)
else D.cash
end as cash
from
(
select * from
(
select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate
from table2
group by username
order by convert(int,username)
) as A
CROSS join
(
select distinct username from table2
) as B
) as C
left join
(
select outdate,username,min(cash) as cash from table2
group by outdate,username
) as D
on(C.username=D.username and datediff(d,C.outdate,D.outdate)=0)
order by C.outdate,convert(int,C.username)
返回结果:
outdate username cash
2001-10-01 00:00:00.000 1 90
2001-10-01 00:00:00.000 2 100
......
2002-01-08 00:00:00.000 100 50
分享到:
相关推荐
C#.NET面试题100题是一份涵盖了广泛C#编程和.NET框架核心概念的集合,旨在帮助求职者准备IT行业的技术面试。这份资源包含了多种类型的题目,从基础语法到高级特性和设计模式,旨在全面考察候选人的技能和理解。 1. ...
以下是对这100道Java面试题可能涉及的知识点的详细解读: 1. **基础语法**:面试题可能会考察Java的基础特性,如数据类型、变量、运算符、流程控制语句(if、switch、for、while等)、方法定义与调用、类与对象的...
7. **程序员面试题精选100题.pdf**:这份资料挑选了程序员面试中常见的100个问题,涵盖C++的各个核心知识点,对面试者进行全面评估。 8. **~三十七章集锦by_July.docx**:这份文档可能包含37个章节的面试题,每个...
2023最新100道MySQL面试题( 附答案解析)2023最新100道MySQL面试题( 附答案解析)2023最新100道MySQL面试题( 附答案解析)2023最新100道MySQL面试题( 附答案解析) 2023最新100道MySQL面试题( 附答案解析) ...
### 前端面试题知识点 #### 1. 面试题目的类型及内容 - **自我介绍**:不仅仅要提供基本信息,还需突出个人特点和优势。 - **开放性题目**:考察应聘者的应变能力、思维深度和广度。 - **项目介绍**:阐述具体参与...
这100道经典Java面试题涵盖了广泛的Java应用和知识点,旨在帮助求职者准备技术面试,同时也是开发者自我提升的良好资源。以下是一些关键的知识点,它们可能出现在这些面试题中: 1. **基础语法**:包括变量、数据...
C语言面试100题(含答案)。 例题1: /* 下列给定程序的功能是:读入一个整数k(2=),打印它的所有质因子(即所有素数的因子)。例如,若输入整数2310,则应输出:2、3、5、7、11。 请改正程序中的错误,使程序能...
java100道面试题
《程序员面试题精选100题—何海涛》是一份详实的IT面试准备资料,由何海涛整理发布,旨在帮助应届毕业生和求职者准备面向微软、谷歌等知名科技公司的面试。此资料不仅收录了精选的100道面试题目,还提供了详细的解题...
大数据面试题 100道 多线程面试59题(含答案) 最新JAVA面试题总结之基础/框架/数据库/JavaWeb/Redis BIO,NIO,AIO,Netty面试题 35道 BTA 常问的 Java基础39道常见面试题及详细答案 Dubbo面试题 47道 ElasticSearch...
3. **大数据面试题 100道**: - **Hadoop**:分布式文件系统HDFS,MapReduce计算模型,YARN资源调度器。 - **Spark**:内存计算,DataFrame/Dataset API,Spark SQL,流处理Spark Streaming。 - **Hive**:基于...
100道最新Java面试题,常见面试题及答案汇总
Hadoop面试题:100道 Zookeeper面试题:21道 Hive面试题:47道 Flume面试题:11道 Kafka面试题:59到 HBase面试题:36道 Spark面试题:97道 Flink面试题:40道 数仓面试题:25道 综合面试题:43道 数据库(MySQL)...
java面试100题及面试技巧总结,自己整理总结的java面试技巧及面试题。 java面试100题及面试技巧总结,自己整理总结的java面试技巧及面试题。 java面试100题及面试技巧总结,自己整理总结的java面试技巧及面试题。 ...
**知识点**:本题考查如何设计一个支持`push`、`pop`和`min`操作的栈数据结构。其中`min`操作应该返回栈中的最小元素。 **解题思路**: 1. **辅助栈**:维护一个辅助栈,用于存储最小值。每当主栈`push`一个元素时...
ABAP 100 道面试题 ABAP 是 SAP 公司开发的一种高级编程语言,用于开发 SAP 系统中的应用程序。本文总结了 ABAP 100 道面试题,涵盖了 ABAP 程序的结构、 Field Symbols 和 Field Groups、BDC 程序、Batch Input ...
C#面试题100例 本资源提供了100多个C#面试题,涵盖了C#语言的各个方面,包括ASP.NET、委托、事件、索引器、排序算法等。这些题目可以帮助开发者更好地理解C#语言的特性和使用方法,并提高面试的通过率。 1. ASP...
### C++相关高频经典面试题知识点详解 #### 1. C++中的数据类型 - **基本数据类型**:包括整型(int, short, long, long long)、浮点型(float, double)、字符型(char)等。 - **复合数据类型**:如数组(array)、...
【标题】: "面试必备:精选100道前端面试题" 【描述】: "这份资料包含了一系列前端面试中常见的问题,涵盖了CSS、JavaScript、jQuery和Vue等方面,旨在帮助初级和中级开发者准备面试。” 【标签】: "面试题 初中级...
java 面试宝典其中包含了100多道常见的面试题,及n道笔试题。