我在 SQLite 中创建了一个大约 3M 行的数据库,我也用它来测试函数或小实验。我的最后一个实验是检查随机函数的分布,所以我写了这个查询:
SELECT b.a , count(*)
FROM(
SELECT abs(random()) % 10 a
FROM fdic) b
GROUP BY b.a
ORDER BY b.a
它适用于每个 SQLite 数据库,只需将表 fdic 替换为您的表即可。 我得到以下回复:
a | 计数(*) |
---|---|
1 | 318161 |
9 | 316810 |
5 | 317591 |
9 | 316006 |
2 | 317502 |
6 | 317131 |
6 | 316093 |
6 | 318442 |
2 | 317923 |
6 | 316793 |
当然,由于 random() 函数,你不会得到两次相同的答案。但如果你分析答案有两个问题,第一个是不“分组”,例如有4倍的值6,两倍的值2等等。 第二个问题是不排序,值未排序。 所以在报告错误之前,我想问你:
您注意到我的查询中有错误吗?
(带有fdic表的数据库已上线,不知道Stackoverflow是否允许发布地址,如果需要数据库请在评论中询问)
sqlite> EXPLAIN SELECT b.a , count(*) FROM(SELECT abs(random()) % 10 a FROM fdic) b GROUP BY b.a ORDER BY b.a;
addr opcode p1 p2 p3 p4 p5 comment
---- ------------- ---- ---- ---- ------------- -- -------------
0 Init 0 46 0 0 Start at 46
1 Noop 2 4 0 0
2 SorterOpen 3 1 0 k(1,B) 0
3 Integer 0 2 0 0 r[2]=0; clear abort flag
4 Null 0 5 5 0 r[5..5]=NULL
5 Gosub 4 42 0 0
6 OpenRead 1 2 0 0 0 root=2 iDb=0; fdic
7 Rewind 1 15 0 0
8 Function 0 0 10 random(0) 0 r[10]=func()
9 Function 0 10 9 abs(1) 0 r[9]=func(r[10])
10 Remainder 11 9 8 0 r[8]=r[9]%r[11]
11 ClrSubtype 8 0 0 0 r[8].subtype = 0
12 MakeRecord 8 1 9 0 r[9]=mkrec(r[8])
13 SorterInsert 3 9 0 0 key=r[9]
14 Next 1 8 0 1
15 OpenPseudo 4 8 1 0 1 columns in r[8]
16 SorterSort 3 45 0 0 GROUP BY sort
17 SorterData 3 8 4 0 r[8]=data
18 Column 4 0 6 0 r[6]= cursor 4 column 0
19 Compare 5 6 1 k(1,B) 0 r[5] <-> r[6]
20 Jump 21 25 21 0
21 Move 6 5 1 0 r[5]=r[6]
22 Gosub 3 32 0 0 output one row
23 IfPos 2 45 0 0 if r[2]>0 then r[2]-=0, goto 45; check abort flag
24 Gosub 4 42 0 0 reset accumulator
25 AggStep 0 0 7 count(0) 0 accum=r[7] step(r[0])
26 Integer 1 1 0 0 r[1]=1; indicate data in accumulator
27 SorterNext 3 17 0 0
28 Gosub 3 32 0 0 output final row
29 Goto 0 45 0 0
30 Integer 1 2 0 0 r[2]=1; set abort flag
31 Return 3 0 0 0
32 IfPos 1 34 0 0 if r[1]>0 then r[1]-=0, goto 34; Groupby result generator entry point
33 Return 3 0 0 0
34 AggFinal 7 0 0 count(0) 0 accum=r[7] N=0
35 Function 0 0 10 random(0) 0 r[10]=func()
36 Function 0 10 9 abs(1) 0 r[9]=func(r[10])
37 Remainder 11 9 12 0 r[12]=r[9]%r[11]
38 ClrSubtype 12 0 0 0 r[12].subtype = 0
39 Copy 7 13 0 0 r[13]=r[7]
40 ResultRow 12 2 0 0 output=r[12..13]
41 Return 3 0 0 0 end groupby result generator
42 Null 0 7 7 0 r[7..7]=NULL
43 Integer 0 1 0 0 r[1]=0; indicate accumulator empty
44 Return 4 0 0 0
45 Halt 0 0 0 0
46 Transaction 0 0 2 1 1 usesStmtJournal=0
47 Integer 10 11 0 0 r[11]=10
48 Goto 0 1 0 0
参见第8行和第35行:子查询执行了两次。这种情况可能发生在许多数据库引擎中,而不仅仅是 SQLite。通常,这应该不重要,因为重复查询不会改变结果。