SQLite是一个被低估的数据库,但也有人认为它是一个不适合生产环境的玩具数据库。事实上,SQLite是一个非常可靠的数据库,它可以处理TB级的数据,但它没有网络层。接下来,本文将和大家一起探讨近一年来SQLite最新的SQL特性。SQLite“只是”一个库,它不是传统意义上的服务器。因此,在某些情况下,确实是不合适的。但是,在其他不少场合,它却是最合适的选择。SQLite声称是部署和使用最广泛的数据库引擎。我认为这是可能的,因为SQLite没有版权限制。每当开发人员想要使用SQL将结构化数据存储在文件中时,SQLite应该是首选解决方案。SQLite的SQL方言也非常强大。它比MySQL早四年开始支持with语句。它最近还实现了对窗口函数的支持,仅比MySQL晚了五个月。接下来本文将介绍SQLite在2018年新增的SQL函数,即SQLite从3.22.0版本到3.26.0版本新增的SQL函数。具体内容包括:BooleanliteralsandjudgmentwindowfunctionFilterclauseInsert...onconflict("Upsert")RenamecolumnonModern-SQL.comNextBoolean变量和判断SQLite支持“false”布尔值:它接受Boolean作为名字类型,但它将其视为整数(很像MySQL)。真值true和false分别用值1和0来表示(这点和C语言中一样)。SQLite从3.23.0版本开始,将关键字true和false分别用数字1和0表示,支持is[not]true|的判断语句。错误的。现在,它不再支持关键字unknown。开发人员可以改用null,因为unknown和null具有相同的布尔值。在INSERT和UPDATE语句中,字面量true和false可以大大提高values和set子句的可读性。是[不]正确|false这个判断语句很有用,它和比较运算的意义不同:我们来比较一下WHEREc<>FALSE和WHEREcISNOTFALSE在上面的例子中,如果c为null,那么c<>false的结果是未知。这是因为WHERE子句只接受结果为true的值,它会过滤掉结果为false或unknown的值。这样做时,它会从结果中删除相应的行。相应地,如果c为null,则c不为假的判断结果为真。因此,第二个WHERE子句也将包含c为空的行。实现相同效果的另一种方法是添加单独的子句来处理空值。即使用语句:WHEREc<>FALSEORcISNULL这种语句形式较长,并且有一些冗余语句(c被使用了两次)。长话短说,or...is-null语句可以替换为isnotfalse语句。详情请参考《基于三值结果的二元决策》。SQLite对booleanliterals和booleanjudgements的支持现在已经和其他开源数据库接近了,唯一不同的是SQLite不支持is[not]unknown(可以用is[not]null代替)。有趣的是,这些功能在下面提到的商业产品中尚不可用。0:只支持真、假。Notknown不支持,必要时使用null1:不支持is[not]unknown,必要时使用is[not]null代替windowfunctionSQLite3.25.0引入了windowfunction。如果你知道窗口函数,你也知道这是一个大问题。如果您不知道窗口函数,请自己学习如何使用它们。本文不会具体解释窗口函数,但请相信我:它是“现代”SQL最重要的特性。SQLite对over子句的支持与其他数据库非常接近。唯一值得注意的限制是范围语句不支持数字或间隔距离(仅支持当前行和无限前|后)。自sqlite3.25.0发布以来,SQLServer和PostgreSQL具有相同的限制。PostgreSQL11消除了这个限制。0:无变化1:Range定义不支持datetime类型2:Range范围不接受关键字(只支持unbounded和currentrow)SQLite对窗口函数的支持是业界领先的。它不支持的特性在其他一些主要产品中也不支持(distinct、width_bucket、respect|ignorenulls和fromfirst|laststatementsinaggregationstatements)。0:也没有ORDERBY语句1:不允许负偏移,null的具体处理:lead(,'IGNORENULLS'),这里是一个字符串参数2:没有默认值(第三个参数),不支持respect|ignorenullsstatement3:negativeoffsetisnotallowed,ignorenullsstatement4:negativeoffsetisnotallowed5:respect|ignorenullsstatement6:negativeoffsetisnotallowed,respect|ignoreisnotsupportedNullsstatement7:具体处理nulls:first_value(,1,null,'IGNORENULLS'),这里是一个字符串参数。8:不支持ignorenulls语句9:不支持ignorenulls语句和fromlaststatementfilter语句虽然filter语句只是语法糖——你也可以很容易地使用表达式来达到相同的结果——我认为是还必不可少更少的语法糖,因为它使人们更容易学习和理解SQL语句。看看下面的select子句,你觉得哪一个更容易理解?SELECTSUM(revenue)total_revenue,SUM(CASEWHENproduct=1THENrevenueEND)prod1_revenue...andSELECTSUM(revenue)total_revenue,SUM(revenue)FILTER(WHEREproduct=1)prod1_revenue...这个例子很好用filter子句的作用总结一下:它是聚合函数的后缀,可以在聚合前根据一定的条件过滤掉对应的行。枢轴技术是过滤器子句最常见的用例。这包括将实体属性值(EAV)模型中的属性转换为表列。如果想了解更多,可以参考链接“filter-SelectiveAggregates”(https://modern-sql.com/featur..)。从3.25.0版本开始,SQLite支持使用over子句的聚合函数中的过滤子句,但还不支持使用groupby子句的聚合函数。不幸的是,这意味着您仍然不能在SQLite中使用过滤语句来处理上述情况。您必须像以前一样使用case表达式。我真的希望SQLite在这一点上尽快做到这一点。Insert…onconflict("Upsert")SQLite,从版本3.24.0开始,引入了“upsert”的概念:它是一个插入语句,可以优雅地处理主键和唯一约束之间的冲突。您可以选择忽略这些冲突(在onconflict语句中什么都不做)或更新当前行(在onconflict语句中执行更新)。这是专有的SQL扩展,即它不是标准SQL的一部分,因此在下面的矩阵中显示为灰色。但是,SQLite遵循与PostgreSQL相同的语法来实现此功能。该标准提供了对merge语句的支持。与PostgreSQL不同,SQLite在以下语句中存在问题。INSERTINTOtargetSELECT*FROMsourceONCONFLICT(id)DOUPDATESETval=excluded.val根据文档,这是因为解析器无法确定关键字ON是SELECT语句的连接约束还是upsert子句的开头.您可以通过在查询中添加子句来解决此问题,例如wheretrue。INSERTINTOtargetSELECT*FROMsourceWHEREtrueONCONFLICT(id)DOUPDATESETval=excluded.val0:同时记录insert,update,delete,merge操作的错误信息(“DMLerrorlogging”)1:Onconflictstatementcannotbe如果需要,可以通过添加wheretrue语句来分隔查询的from语句。重命名列SQLite引入的另一个独特功能是重命名基本数据库表中的列1。标准SQL不支持此类功能2。SQLite遵循其他产品常用的重命名列的语法:ALTERTABLE...RENAMECOLUMN...TO0:请参考sp_rename。其他消息2018年,除了SQL语法的变化,SQLite也有一些应用程序编程接口(API)的变化。您可以查看sqlite.com(https://www.sqlite.org/news.html)上的新闻部分以了解更多详细信息。下标:0:SQLite通常遵循PostgreSQL语法,RichardHipp称之为HowPostgreSQLWillDo(WWPD)。1:基准数据库表是指用Createtable语句创建的数据库表。派生数据库表中的列名(如Select语句返回的查询结果集)可以通过SELECT语句、FROM语句或WITH语句来改变2:据我所知,可能是通过一个模拟可更新视图或派生列函数。原文:https://modern-sql.com/blog/2...近期热门文章推荐:1.1000+Java面试题及答案(2022最新版)2.厉害了!Java协程来了。..3.SpringBoot2.x教程,太全面了!4.不要用爆破爆满画面,试试装饰者模式,这才是优雅的方式!!5.《Java开发手册(嵩山版)》最新发布,赶快下载吧!感觉不错,别忘了点赞+转发!
