SQL puzzles and answers读书笔记——财年表

最近开始阅读数据库大师Joe Celko的《SQL PUZZLES AND ANSWERS》一书。这本书每篇都是一个SQL谜题,涉及数据库设计、开发。我看的是英文第二版,在这里做个读书笔记,顺便用T-SQL和PL/SQL来实现其中的代码。

谜题1——财年表

我们首先来创建一张表(以下代码在SQL Server 2008和Oracle上都能运行通过):

create table FiscalYearTable1
(
	fiscal_year int,
	start_date date,
	end_date date
);

这张表存储了每个财年的起始日期和结束日期。用以下查询能找出outside_date所属的财年:

select
	F1.fiscal_year
from
	FiscalYearTable1 as F1
where
	outside_date between F1.start_date and F1.end_date

我们的谜题是:对于这张表加哪些约束能防止错误数据的输入?

讨论与方案

1. 首先能想到的是给每个列加上NOT NULL约束,因为在这张表中存放NULL值没有特别的意义和好处。

2. 作为SQL程序员很快能想到要加PRIMARY KEY约束。对于FiscalYearTable1表可以在fiscal_year列加PRIMARY KEY约束。同样start_date和end_date列也不允许重复值的出现,所以可以加上UNIQUE约束。

3. 约束CHECK(start_date < end_date)非常明显,但却容易被人遗忘。

4. 虽然有了上述约束,但还是无法避免如下的错误:

(2007, ‘2006-10-01’, '2007-09-30')

(2008, ‘2007-10-01’, '2008-09-30’)

(2009, ‘2008-10-01’, '2009-08-30’) <==出错了!

(2010, ‘2009-10-01’, '2010-09-30’)

对于如上start_date月日和end_date月日固定的财年表,可以加更为精确的约束。代码如下:

T-SQL:

create table FiscalYearTable1
(
	fiscal_year int not null primary key,
	start_date date not null,
	constraint valid_start_date
		check((year(start_date) = fiscal_year - 1)
				and (month(start_date) = 10)
				and (day(start_date) = 1)),
	end_date date not null,
	constraint valid_end_date
		check((year(end_date) = fiscal_year)
				and (month(end_date) = 9)
				and (day(end_date) = 30))
);

PL/SQL:

create table FiscalYearTable1
(
  fiscal_year int not null primary key,
  start_date date not null,
  constraint valid_start_date
    check((extract(year from start_date) = fiscal_year - 1)
          and (extract(month from start_date) = 10)
          and (extract(day from start_date) = 1)),
  end_date date not null,
  constraint valid_end_date
    check((extract(year from end_date) = fiscal_year)
          and (extract(month from end_date) = 9)
          and (extract(day from end_date) = 30))
);

5. 有些公司的财年计算方式和4中的不同,如以52周为一个财年。这种情况下就无法使用4中对start_date和end_date的约束了,我们可以加如下约束(52周 × 7天 = 364天):

CHECK((end_date – start_date) = INTERVAL 364 DAYS)

转载于:https://www.cnblogs.com/DBFocus/archive/2010/08/16/1801012.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是经典的C语言书籍推荐: 1. 《C程序设计语言》(The C Programming Language)- Brian W. Kernighan和Dennis M. Ritchie 2. 《C专家编程》(Expert C Programming)- Peter Van Der Linden 3. 《C和指针》(C Pointers and Memory Management)- Kamran Husain 4. 《C陷阱和缺陷》(C Traps and Pitfalls)- Andrew Koenig 5. 《C编程的艺术》(The Art of C Programming)- Eric S. Roberts 6. 《C语言深度剖析》(Deep C)- Olaf Chitil 7. 《C语言程序设计》(Programming in C)- Stephen G. Kochan 8. 《C语言核心技术》(C Core Language)- Doug Abbott 9. 《C程序员必读经典》(The C Programmer's Handbook)- Greg Perry 10. 《C语言参考手册》(C Pocket Reference)- Peter Prinz和Tony Crawford 11. 《C++ Primer》- Stanley B. Lippman、Josée Lajoie和Barbara E. Moo 12. 《C++ Primer Plus》- Stephen Prata 13. 《C++语言的设计与演化》(The Design and Evolution of C++)- Bjarne Stroustrup 14. 《C++程序设计》(C++ Programming)- DS Malik 15. 《C++标准库》(The C++ Standard Library)- Nicolai M. Josuttis 16. 《C++对象模型》(Inside the C++ Object Model)- Stanley B. Lippman 17. 《C++编程思想》(Thinking in C++)- Bruce Eckel 18. 《C++程序设计语言》(The C++ Programming Language)- Bjarne Stroustrup 19. 《C++沉思录》(C++ Puzzles and Paradoxes)- Steve Summit 20. 《C++编程规范》(C++ Coding Standards)- Herb Sutter和Andrei Alexandrescu 这些书籍对于学习C语言编程和C++编程非常有帮助,都是经典的教材和参考书籍。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值