<script type="text/javascript">
</script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
数据抽取
理论上的关系型,数据是以关系的形式存在。通常我们都可以把它们视为一种集合。这样,数据一般是以无序的形式存在的。这种做法的好处自不用多加讨论了,不过我们也得承认,有时这样也会带给我们一些麻烦。我最近就遇到这么一件。
我在网上遇上我的一个老同学,他提出了这样一个问题。有一个表(假设就叫myTable),表中有三个整型字段(假设就叫A11,A12,A13),其上有一个唯一键约束。现在他想要在这个表的数据中取一些样品。他希望从中A13的各个取值中,各取一条记录。然后我问他,对A11和A12有什么要求吗?他说,没有,怎么取都可以,有没有规律都行。我想当然的说,简单,给我二十分钟。
有一个笑话不知你们听过没有。说很久以前,一个大数学家讲课,有学生问他能不能证明四色定理。他说,那容易,我现在就证给你们……然后他写啊写啊……想啊想啊……一直想到下课也没证出来,然后外面打了一个大大的响雷,他自嘲说,上帝也被我的狂妄激怒了……
什么,你问我刚才的问题怎么样了?我告诉你,二十分种,不不,四十分钟,不不,好像是一个小时……后来到半夜了,外面开始打雷……我对我的同学说,老兄,我错了,让我把这问题拿回去想想先……
以下是一个示例,我随便录了些数据进去
A11A12A13
---------------------------------
000
001
011
111
112
122
222
221
223
213
233
331
332
323
321
322
311
312
313
一开始,我是想用一个SELECTMAX(A11),MAX(A12),A13FROMmyTableGROUPBYA13,后来用脚趾头想了想,发现不可能。因为MAX(A11)和MAX(A12)都只依赖于分组子句GROUPBYA13。显然这样MAX(A11)和MAX(A12)不一定会是同一条记录中的数据。就像下面这样:
A13
---------------------------------
000
331
332
333
注意,其实3,3,3这一行是不存在的。
然后我想,SELECTMAX(A11),MAX(A12),A13FROMmyTableGROUPBYA13,A12行不行?用试了试,也不对。因为这样的话,它会先按A13,A12来分组所返回的结果集,所以会比我们要的数据多的多。就像下面这样
A13
---------------------------------
000
001
311
312
313
321
322
323
331
332
233
诸如此类的傻事我还干了很多,后来我终于想明白我要什么数据了:取A12,A13,使得在所有按A13的值分组后,取每组中最大的A12,然后取整记录,使得A11是A12和A13满足前述条件后的最大的一个值。这样,我写出了一个语句:
SELECT
(SELECTMAX(I.A11)FROMmyTableIWHEREI.A13=O.A13ANDI.A12=MAX(O.A12))A11
,MAX(O.A12)A12
,O.A13A13
FROMmyTableO
GROUPBYO.A13
这行语句返回值如下:
A11A12A13
---------------------------------
000
331
332
233
同样的,我们可以解释它为最两个结果集,一个是SELECTMAX(A11),MAX(A12),A13FROMmyTableGROUPBYA13,一个是SELECTMAX(A12),A13FROMmyTableGROUPBYA13,A12,然所按A12和A13进行等值联接,这就是:
SELECTMAX(L.A11)A11
,MAX(L.A12)A12
,L.A13A13
FROMmyTableL
JOINmyTableR
ONL.A13=R.A13
GROUPBYL.A13,L.A12
HAVINGL.A12=MAX(R.A12)
我个觉得这样子比较清爽,不知各位以为如何?
事实上,这一类的 数据抽取,不可能用一个简单查询得到,因为其中有一个字段要同时参予分组和统计。只有(事实上是只要)把我们的问题用SQL语言的思考方式描述清楚,答案也就得到了,一切就这么简单。
对于一类完全按行随机抽取的问题,除了化为Topn问题解决外,还有一个好主意就是在支持物理行号的数据库系统中,用rowid或标识列之类的技术来解决,这样比较简单,就不多说了。
补充一句,以前我说过InterBase不支持自动标识列,但实际上,它也可以间接的实现。在InterBase中,我们可以Create一种叫generator的全局变量,然后用一个触发器,结合一个函数叫GEN_ID的,就可以做到。虽说有点麻烦,但并非不可能。详细情况,大家可以查询InterBase有关技术文档。 1 <script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript">
</script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
数据抽取
理论上的关系型,数据是以关系的形式存在。通常我们都可以把它们视为一种集合。这样,数据一般是以无序的形式存在的。这种做法的好处自不用多加讨论了,不过我们也得承认,有时这样也会带给我们一些麻烦。我最近就遇到这么一件。
我在网上遇上我的一个老同学,他提出了这样一个问题。有一个表(假设就叫myTable),表中有三个整型字段(假设就叫A11,A12,A13),其上有一个唯一键约束。现在他想要在这个表的数据中取一些样品。他希望从中A13的各个取值中,各取一条记录。然后我问他,对A11和A12有什么要求吗?他说,没有,怎么取都可以,有没有规律都行。我想当然的说,简单,给我二十分钟。
有一个笑话不知你们听过没有。说很久以前,一个大数学家讲课,有学生问他能不能证明四色定理。他说,那容易,我现在就证给你们……然后他写啊写啊……想啊想啊……一直想到下课也没证出来,然后外面打了一个大大的响雷,他自嘲说,上帝也被我的狂妄激怒了……
什么,你问我刚才的问题怎么样了?我告诉你,二十分种,不不,四十分钟,不不,好像是一个小时……后来到半夜了,外面开始打雷……我对我的同学说,老兄,我错了,让我把这问题拿回去想想先……
以下是一个示例,我随便录了些数据进去
A11A12A13
---------------------------------
000
001
011
111
112
122
222
221
223
213
233
331
332
323
321
322
311
312
313
一开始,我是想用一个SELECTMAX(A11),MAX(A12),A13FROMmyTableGROUPBYA13,后来用脚趾头想了想,发现不可能。因为MAX(A11)和MAX(A12)都只依赖于分组子句GROUPBYA13。显然这样MAX(A11)和MAX(A12)不一定会是同一条记录中的数据。就像下面这样:
A13
---------------------------------
000
331
332
333
注意,其实3,3,3这一行是不存在的。
然后我想,SELECTMAX(A11),MAX(A12),A13FROMmyTableGROUPBYA13,A12行不行?用试了试,也不对。因为这样的话,它会先按A13,A12来分组所返回的结果集,所以会比我们要的数据多的多。就像下面这样
A13
---------------------------------
000
001
311
312
313
321
322
323
331
332
233
诸如此类的傻事我还干了很多,后来我终于想明白我要什么数据了:取A12,A13,使得在所有按A13的值分组后,取每组中最大的A12,然后取整记录,使得A11是A12和A13满足前述条件后的最大的一个值。这样,我写出了一个语句:
SELECT
(SELECTMAX(I.A11)FROMmyTableIWHEREI.A13=O.A13ANDI.A12=MAX(O.A12))A11
,MAX(O.A12)A12
,O.A13A13
FROMmyTableO
GROUPBYO.A13
这行语句返回值如下:
A11A12A13
---------------------------------
000
331
332
233
同样的,我们可以解释它为最两个结果集,一个是SELECTMAX(A11),MAX(A12),A13FROMmyTableGROUPBYA13,一个是SELECTMAX(A12),A13FROMmyTableGROUPBYA13,A12,然所按A12和A13进行等值联接,这就是:
SELECTMAX(L.A11)A11
,MAX(L.A12)A12
,L.A13A13
FROMmyTableL
JOINmyTableR
ONL.A13=R.A13
GROUPBYL.A13,L.A12
HAVINGL.A12=MAX(R.A12)
我个觉得这样子比较清爽,不知各位以为如何?
事实上,这一类的 数据抽取,不可能用一个简单查询得到,因为其中有一个字段要同时参予分组和统计。只有(事实上是只要)把我们的问题用SQL语言的思考方式描述清楚,答案也就得到了,一切就这么简单。
对于一类完全按行随机抽取的问题,除了化为Topn问题解决外,还有一个好主意就是在支持物理行号的数据库系统中,用rowid或标识列之类的技术来解决,这样比较简单,就不多说了。
补充一句,以前我说过InterBase不支持自动标识列,但实际上,它也可以间接的实现。在InterBase中,我们可以Create一种叫generator的全局变量,然后用一个触发器,结合一个函数叫GEN_ID的,就可以做到。虽说有点麻烦,但并非不可能。详细情况,大家可以查询InterBase有关技术文档。 1 <script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript">
</script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>