Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何计算SQLite中的中值?_Sqlite_Median - Fatal编程技术网

如何计算SQLite中的中值?

如何计算SQLite中的中值?,sqlite,median,Sqlite,Median,我想计算数字行中的中值。如何在SQLite 4中做到这一点?让我们说中位数是有序列表中间的元素。< /P> SQLite(4或3)没有任何内置函数,但可以手动完成: SELECT x FROM MyTable ORDER BY x LIMIT 1 OFFSET (SELECT COUNT(*) FROM MyTable) / 2 当记录数为偶数时,通常将中位数定义为两个中间记录的平均数。 在这种情况下,平均值可以这样计算: SELECT AVG(x) FROM (SELECT

我想计算数字行中的中值。如何在SQLite 4中做到这一点?

让我们说中位数是有序列表中间的元素。< /P> SQLite(4或3)没有任何内置函数,但可以手动完成:

SELECT x
FROM MyTable
ORDER BY x
LIMIT 1
OFFSET (SELECT COUNT(*)
        FROM MyTable) / 2

当记录数为偶数时,通常将中位数定义为两个中间记录的平均数。 在这种情况下,平均值可以这样计算:

SELECT AVG(x)
FROM (SELECT x
      FROM MyTable
      ORDER BY x
      LIMIT 2
      OFFSET (SELECT (COUNT(*) - 1) / 2
              FROM MyTable))
将奇数和偶数情况组合在一起,结果如下:

SELECT AVG(x)
FROM (SELECT x
      FROM MyTable
      ORDER BY x
      LIMIT 2 - (SELECT COUNT(*) FROM MyTable) % 2    -- odd 1, even 2
      OFFSET (SELECT (COUNT(*) - 1) / 2
              FROM MyTable))

sqlite3有一个各种数学函数的扩展包。它包括中位数等群函数

这将是更多的工作比CL的答案,但可能是值得的,如果你认为你需要任何其他功能

(是如何编译和加载SQLite扩展的指南。)

从描述:

使用可加载扩展机制为SQL查询提供数学和字符串扩展函数。数学:acos,asin,atan,atn2,atan2,acosh,asinh,atanh,差,度,弧度,cos,sin,tan,cot,cosh,sinh,tanh,coth,exp,log,log10,power,sign,sqrt,square,ceil,floor,pi。字符串:replicate、charindex、leftstr、righstr、ltrim、rtrim、trim、replace、reverse、property、padl、padr、padc、strfilter。聚合:标准偏差、方差、模式、中位数、下四分位数、上四分位数

更新2015-04-12:修复“未定义符号:sinh” 正如在注释中提到的,尽管编译成功,但此扩展可能无法正常工作

例如,编译可以工作,在Linux上,您可以将生成的.so文件复制到
/usr/local/lib
。但是,
sqlite3
shell中的
.load/usr/local/lib/libsqlitefunctions
可能会生成以下错误:

Error: /usr/local/lib/libsqlitefunctions.so: undefined symbol: sinh
以这种方式编译它似乎是可行的:

gcc -fPIC -shared extension-functions.c -o libsqlitefunctions.so -lm
.so
文件复制到
/usr/local/lib
时,不会显示类似错误:

sqlite> .load /usr/local/lib/libsqlitefunctions

sqlite> select cos(pi()/4.0);
---> 0.707106781186548
我不知道为什么gcc的选项顺序在这种特殊情况下很重要,但显然它确实如此

注意到这一点要归功于的评论,SELECT AVG(x)只返回格式为YYYY-MM-DD的日期值的年份,因此我稍微调整了CL的解决方案以适应日期:

SELECT DATE(JULIANDAY(MIN(MyDate)) + (JULIANDAY(MAX(MyDate)) - JULIANDAY(MIN(MyDate)))/2) as Median_Date
FROM (
   SELECT MyDate
      FROM MyTable
      ORDER BY MyDate
      LIMIT 2 - ((SELECT COUNT(*) FROM MyTable) % 2) -- odd 1, even 2
      OFFSET (SELECT (COUNT(*) - 1) / 2 FROM MyTable)
);

有一个带有时间戳、标签和延迟的日志表。我们希望看到每个标签的延迟中值,按时间戳分组。使用前导零将所有延迟值格式化为15个字符长度,将其串联,并将定位值减半。。这是中位数

select L, --V, 
       case when C % 2 = 0 then
       ( substr( V, ( C - 1 ) * 15 + 1, 15) * 1 + substr( V, C * 15 + 1, 15) * 1 ) / 2
       else
        substr( V, C * 15 + 1, 15) * 1
       end as MEDST
from (
    select L, group_concat(ST, "") as V, count(ST) / 2 as C
    from (
        select label as L, 
               substr( timeStamp, 1, 8) * 1 as T, 
               printf( '%015d',latency) as ST
        from log
        where label not like '%-%' and responseMessage = 'OK'
        order by L, T, ST ) as XX
    group by L
    ) as YY

Dixtroy通过group_concat()提供了最佳解决方案。 以下是这方面的完整示例:

DROP TABLE [t];
CREATE TABLE [t] (name, value INT);
INSERT INTO t VALUES ('A', 2);
INSERT INTO t VALUES ('A', 3);
INSERT INTO t VALUES ('B', 4);
INSERT INTO t VALUES ('B', 5);
INSERT INTO t VALUES ('B', 6);
INSERT INTO t VALUES ('C', 7);
此表中的结果:

name|value
A|2
A|3
B|4
B|5
B|6
C|7
现在我们使用来自Dextroy的(稍加修改的)查询:

SELECT name, --string_list, count, middle,
    CASE WHEN count%2=0 THEN
        0.5 * substr(string_list, middle-10, 10) + 0.5 * substr(string_list, middle, 10)
    ELSE
        1.0 * substr(string_list, middle, 10)
    END AS median
FROM (
    SELECT name, 
        group_concat(value_string,"") AS string_list,
        count() AS count, 
        1 + 10*(count()/2) AS middle
    FROM (
        SELECT name, 
            printf( '%010d',value) AS value_string
        FROM [t]
        ORDER BY name,value_string
    )
    GROUP BY name
);
…并得到以下结果:

name|median
A|2.5
B|5.0
C|7.0

这是一个很好的解决方案,但如果您想计算“分组依据”结果的中位数而不是整个表,则似乎很难使用它。考虑“选择GRP,min(Var),中位数(VAR),MAX(VALL)从表组通过GRP”。@宏碁-我看到你是正确的。在这种情况下,如果没有数据库对中间值的支持,我就没有一个优雅的单语句解决方案。我想到的是:1)使用GROUPBY子句创建一个表,并以排序形式选择INTO(称此表为“G”),然后添加一个自动增量列(称之为列“i”)。2) 创建一个查询,计算每个组的(max(G.i)+min(G.i))/2.0(称此列为“x”)。3) 使用Pick表,从G中选择条目,其中ABS(G.i-Pick.x)似乎可以使用视图而不是实际的表来执行相同的操作。知道如何安装它吗?文件本身没有多大帮助。@jameshfisher试着在另一个问题中询问它,这里是一个领先的开始。出于好奇,我今晚试着编译扩展。按照文件顶部的C注释中包含的说明进行操作非常简单(您确实阅读了文件并找到了它们,对吗?),但是存在一些bug。它在Ubuntu14.04 LTS上使用gcc进行编译,前提条件是“libsqlite3 dev”,从而生成一个共享库“libsqlitefunctions.so”。同一个Ubuntu的sqlite3在给出SELECT load_extension('./libsqlitefunctions')命令时试图加载它,但抛出了一个错误“undefined symbol:sinh”。这比我预想的要容易得多。干得好!此链接()提供一个已编译的so文件。它起作用了@Kassym Dorsel:从同一文件夹下载上述扩展名functions.c文件和sqlite合并文件,并将其全部解压缩。然后安装MinGw安装程序,并从这里将包“mingw32 base-bin”安装到c:\MinGw中。现在打开一个DOS命令并更改为c:\MinGW\bin,然后运行命令gcc-g-shared“c:\YourPath\extension-functions.c”-o“c:\YourPath\extension-functions.dll”,最后通过.load c:/YourPath/extension-functions.dll在SQLite中加载dll