用js和sql写出按sql server 季度函数累计

在日新月异的前端领域中,前端工程师能做的事情越来越多,自从nodejs出现后,前端越来越有革了传统后端命的趋势,本文就再补一刀,详细解读如何在js代码中执行标准的SQL语句
为什么要在js里写SQL?
随着业务复杂度的增长,前端页面可能出现一些数据逻辑复杂的页面,传统的js逻辑处理起来比较复杂,我们先看两个例子:
比如多规格多库存商品界面,难点在于颜色分类、尺码、价格、库存、限购数量以及对应的图片展示之间有复杂的逻辑关系,用户进行不同的选择时,js要经过多次复杂的查询才能算出结果
比如地区联动查询界面,难点在于:
如何在本地存储地区数据,显然每次拉接口是不现实的,如果存储在storage里,每次使用时,需要有类似JSON.parse类的字符串转化为数组或对象的过程,这个操作在数据量大的时候,会造成页面卡顿,性能极差
三级地区联动查询复杂,如果要从一个县级地区查询到所属的城市和省份,逻辑会比较复杂
上面两个例子,如果用传统js逻辑来写,大家头脑中必定已经设计好了算法,免不了用forEach、filter、some、find等各种ES678新方法,笔者开始也是用了各种酷炫的新方法写出来发现有两个问题:
写完之后逻辑很复杂,似乎没有100行代码实现不了(当然有大神比我活儿好)
即使写了一大堆注释,同事们看起来还是一头雾水(因为逻辑确实很复杂。。。)
笔者做过一段时间php开发(还做过PM、UI、QA等)忽然想能不能用SQL的方式实现呢?经过一番研究,笔者写了这样一个库:
Database.js
Database.js基于Web SQL Database,那么Web SQL Database又是啥?
Web SQL Database是WHATWG(Web 超文本应用技术工作组,HTML5草案提出方)在2008 年 1 月提出的第一份正式草案,但并未包含在 HTML 5 规范之中,它是一个独立的规范,它引入了一套使用 SQL 操作客户端数据库的 API。由于提出时间较早,尽管 W3C 官方在 2011 年 11 月声明已经不再维护 Web SQL Database 规范,但这些 API 已经被广泛的实现在了不同的浏览器里,尤其是手机端浏览器。
Web SQL Database 和 Indexed Database有啥区别?
Indexed Database 更类似于 NoSQL 的形式来操作数据库 , 其中最重要的是 Indexed Database 不使用 SQL 作为查询语言。
笔者为了实现在js里面写SQL的需求,果断采用了前者作为底层技术。
Web SQL Database 三个核心方法:
openDatabase:这个方法使用现有数据库或新建数据库来创建数据库对象
transaction:这个方法允许我们根据情况控制事务提交或回滚
executeSql:这个方法用于执行SQL 查询
代码示例:
<span style="color: # var db = openDatabase('testDB', '1.0', 'Test DB', 2 * 1024 * 1024);
<span style="color: #
<span style="color: #
db.transaction(function (context) {
<span style="color: #
context.executeSql('CREATE TABLE IF NOT EXISTS testTable (id unique, name)');
<span style="color: #
context.executeSql('INSERT INTO testTable (id, name) VALUES (0, "Byron")');
<span style="color: #
context.executeSql('INSERT INTO testTable (id, name) VALUES (1, "Casper")');
<span style="color: #
context.executeSql('INSERT INTO testTable (id, name) VALUES (2, "Frank")');
<span style="color: #
对于没有SQL经验的前端同学来讲,上面代码看起来显然有点陌生,也不太友好,于是Database.js诞生了:
笔者以业务当中的一个需求举例:&转转游戏业务列表页筛选菜单是一个三级联动菜单,每个菜单变动都会影响其他菜单数据,如图:
原始JSON数据结构
可以看出是3级嵌套结构,笔者处理成了扁平化的数据结构(过程略),并分别存入三个数据库,分别存储游戏名称、游戏平台、商品类型,如下图:
举例游戏名称数据结构如下图:
通过chrome控制台Application面板可以直接看到数据库,结构、数据清晰可见
核心代码如下:
* 打开数据库
* @returns {Promise.&void&}
openDataBase(){
//打开数据库,没有则创建
db.openDatabase('GameMenu',1,'zzOpenGameMenu').then(res=&{
//检测数据库是否存在
db.isExists('game').then(res=&{
<span style="color: #
//数据库已经存在,直接使用,将数据交付给页面UI组件
<span style="color: #
this.setSelectData()
<span style="color: #
}).catch(e=&{
<span style="color: #
//数据库不存在,请求接口并处理数据,然后存入数据库
<span style="color: #
this.getData()
<span style="color: #
<span style="color: #
}).catch(e=&{
<span style="color: #
console.err(e)
<span style="color: #
<span style="color: #
<span style="color: #
<span style="color: #
* 获取分类数据并存储到数据库
<span style="color: #
* @returns {Promise.&void&}
<span style="color: #
<span style="color: #
async getData(){
<span style="color: #
//接口请求数据并处理成三个扁平数组
<span style="color: #
let data =
await this.getMenuData()
<span style="color: #
for(let i in data){
<span style="color: #
//创建表并存储数据
<span style="color: #
db.create(i,data[i])
<span style="color: #
<span style="color: #
//将数据交付给页面UI组件
<span style="color: #
this.setSelectData()
<span style="color: #
当任意菜单选择变更时,三列数据将重新查询,核心代码如下:
* 重新查询数据
* @param data 点击菜单携带的数据
* @param index 点击菜单的序号
* @param all 三个菜单当前选中数据
async onSelect(data,index,all){
let target = [],condition = {}
//业务逻辑:处理查询条件
<span style="color: #
if(all['0'] && all['0']['name']!=defaultData[0].default.name)condition['gameName'] = all['0']['name']
<span style="color: #
if(all['1'] && all['1']['name']!=defaultData[1].default.name)condition['platName'] = all['1']['name']
<span style="color: #
if(all['2'] && all['2']['name']!=defaultData[2].default.name)condition['typeName'] = all['2']['name']
<span style="color: #
<span style="color: #
//创建三个查询任务
<span style="color: #
let tasks = ['game','plat','type'].map((v,k)=&{
<span style="color: #
//使用db.select方法查询
<span style="color: #
return db.select(v,this.formatCondition(v,condition),'name,value','rowid desc','name').then((res)=&{
<span style="color: #
target.push({
<span style="color: #
options:res.data,
<span style="color: #
defaultOption:defaultData[k].default,
<span style="color: #
clickHandle:this.onSelect
<span style="color: #
<span style="color: #
<span style="color: #
<span style="color: #
//执行查询
<span style="color: #
await Promise.all(tasks)
<span style="color: #
//将数据交付给联动菜单组件使用
<span style="color: #
this.selectData = target
<span style="color: #
以上代码即可完成联动菜单所需要的数据管理工作,看起来是不是比较清晰?
使用Database.js的优势
1.将数据结构化存储于Storage中,避免了以文本形式存入Storage或cookie中再解析的性能消耗流程。
2.将复杂数据清晰的在前端进行管理和使用,代码逻辑更清晰,数据查询更简洁!
Database.js使用文档
openDatabase
功能:打开数据库,不存在则创建
语法:openDatabase(dbName,dbVersion,dbDescription,dbSize,callback)
dbName:数据库名
dbVersion:数据库版本(打开已存在数据库时,版本号必须一致,否则会报错)
dbDescription:数据库描述
dbSize:数据库预设大小,默认1M
callback:回调函数
功能:执行sql语句,支持多表查询
语法:query(sqlStr,args = [],callback,errorCallback)
sqlStr:sql语句
args(Array):传入的数据,替换sql中的?符号
callback:成功回调
errorCallback:失败回调
<span style="color: #
//插入数据
<span style="color: #
db.query('INSERT INTO testTable(id,title) VALUES (?,?)',[1,'这是title'])
<span style="color: #
<span style="color: #
//多表查询
<span style="color: #
db.query('select game.*,plat.* from game left join plat on game.name = plat.gameName')
功能:检测表是否存在
语法:isExists(tableName)
tableName:表名
createTable
功能:创建一张表
语法:createTable(tableName,fields)
tableName:表名
fields:表结构(需指定字段类型)
<span style="color: #
db.createTable('testTable',{
<span style="color: #
name:'varchar(200)',
<span style="color: #
price:'int(100)'
<span style="color: #
功能:插入一条或多条数据
语法:insert(tableName,data)
tableName:表名
data(Object or Array):插入的数据,多条数据请传入数组类型
示例:&javascript //插入单条 db.insert('testTable',{ name:'商品1', price:10 }) //插入多条 db.insert('testTable',[ {name:'商品1',price:10}, {name:'商品2',price:20}, {name:'商品3',price:30}, ])
将数据存入数据库的常规流程是先createTable,然后再insert,如果你觉得这样麻烦,可以试一下create方法:
功能:直接创建数据库并存入数据
注意:类库会根据传入的数据类型自动设置数据库的字段类型,这样可以覆盖大多数需求,但如果你的数据中,同一个字段中有不同的数据类型,有可能不能兼容,建议还是使用常规流程手动设置类型
语法:create(tableName,data)
tableName:表名
data(Object or Array):插入的数据,多条数据请传入数组类型
<span style="color: #
//直接创建表并存储
<span style="color: #
db.create('testTable',[
<span style="color: #
{name:'商品1',price:10},
<span style="color: #
{name:'商品2',price:20},
<span style="color: #
{name:'商品3',price:30},
<span style="color: #
功能:删除数据
语法:delete(tableName,condition)
tableName:表名
condition(String or Obejct):查询条件
<span style="color: #
//删除一条数据
<span style="color: #
db.delete('testTable',{name:'商品1'})
关于condition:&1、传入array形式时,默认查询条件连接方式是AND,如果需要用OR等方式,可以在condition中传入logic设定,例如{logic:'OR'}&2、如果查询条件有AND、OR等多种方式,建议使用string方式传入
功能:查询数据
注意:如果需要多表查询,可参照query方法
语法:select(tableName,condition = '',fields = '*',order = '',group = '',limit = '')
tableName:表名
condition(String or Obejct):查询条件
fields(String or Array):返回字段,默认*,支持distinct
order(String or Array):排序规则
group(String or Array):分组规则
limit(String or Array):分页规则
<span style="color: # //查询name=商品1的数据,并按照price倒序
<span style="color: #
db.select('testTable',{
<span style="color: #
name:'商品1'
<span style="color: #
},'*','price desc')
<span style="color: #
<span style="color: #
//查询价格大于0的商品,并用distinct关键字去重
<span style="color: #
db.select('testTable',{
<span style="color: #
price:'&0'
<span style="color: #
},'distinct name,pirce','price desc')
**update**
- 功能:更新数据
- 语法:update(tableName,data,condition = '')
- tableName:表名
- data(String or Obejct):更改数据
- condition(String or Obejct):查询条件
<span style="color: #
//将商品1的价格改为99
<span style="color: #
db.update('testTable',{
<span style="color: #
<span style="color: #
<span style="color: #
name:'商品1'
<span style="color: #
功能:清空表
语法:truncate(tableName)
tableName:表名
功能:删除表
语法:drop(tableName)
tableName:表名
如何使用Database.js
Github地址:
如果你有更好的想法,欢迎与我交流,个人微信号:king
更多前端新鲜文章,请关注我司公众号“大转转FE”
如果你喜欢我们的文章,关注我们的公众号和我们互动吧。
阅读(...) 评论()温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
阅读(2779)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
在LOFTER的更多文章
loftPermalink:'',
id:'fks_',
blogTitle:'如何使用JAVASCRIPT从sqlserver数据库中获得数据?',
blogAbstract:'var conn = new ActiveXObject(\"ADODB.Connection\");conn.Open(\"Data Source=190.190.200.100,1433;Initial Catalog=User ID=Password=\");var strSQL = \"Select * From Data\";var rs = new ActiveXObject(\"ADODB.Recordset\");rs.CursorType = 3; //adOpenStaticrs.LockType = 1; //adLockReadOnlyrs.Open(strSQL, conn)---------------------------------------------------------------',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:2,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'1',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}js快还是sql执行快,请看问题补充_百度知道
js快还是sql执行快,请看问题补充
我现在要得到一个数据,这个数据可以从已经执行的ajax里返回的数据里计算,但是每次都执行的很慢,要相乘判断规则等,如果不从已经执行ajax里返回值取数计算而从新发一个ajax请求用sql计算(sql里可以把这个值计算),那么有可能提高速度吗。
我有更好的答案
这种温度当然是用js来计算了,或者在你第一次请求的时候就计算好,因为js是运行在一台电脑上的,而sql是多台电脑请求,也就是说每请求一次,就会计算一次,效率肯定不高
采纳率:31%
应该不会有提高的sql中计算会耗时连接
为您推荐:
其他类似问题
&#xe675;换一换
回答问题,赢新手礼包&#xe6b9;
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。怎么写求季度累计求和SQL语句_百度知道
怎么写求季度累计求和SQL语句
我有更好的答案
你能不能把你的表结构发出来,还有需要的格式是什么样的也写出来啊
为您推荐:
其他类似问题
&#xe675;换一换
回答问题,赢新手礼包&#xe6b9;
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
如题, 要想书写格式化的sql 必须是多行的。 多行的字符串, 用 nodejs 书写有什么快捷的方式或工具。 一个个+号写过去, 实在太麻烦。
使用的编辑是vim, 有相关的快捷方式推荐更好了
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
没什么特别好的方法,一般对于长字符串有两种写法:
第一,用 \ 换行,注意,这样做是不会在字符串中插入 \n,最终结果将是 'Line 1Line 2Line 3'。
sql = 'Line 1\
第二,用数组再 join,这样做性能会好一些,但写起来跟 + 一样蛋疼。
].join('');
P.S. 如果真的想要写的爽,建议尝试一下 ,如果从 python 过来的人应该会很熟悉且很顺手吧。
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
function a() {
function getString(f) {
return f.toString().replace(/^function[^/*]*?\/\*|\*\/[^*/]*\}$/g, "")
getString(a)
结果(引号仅用于表示起始位置)
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
把 SQL 语句写在一个外部文件中,然后再读取文件内容。有点类似于在前端渲染结构较复杂的 DOM 元素时,使用模板引擎来取代用 + 号拼接字符串的方式。
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
sublime Package: JavaScript Multiline
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
可以参考这个
'select * from',
'where username =',
'username'
].join(' ')
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
我也提供下现在采用的方案:
使用一个orm, 这个orm的特点如下:
1. 完全不支持复杂表连接
2. 极高的缓存命中率
说明:大部分应用中使用的sql复杂度不高, 即使个别需要表连接的也完全可以拆分成两条sql。咋看可能增加了代码量,但这样做避免了复杂sql带来的高负载,同时拆分成简单sql能够很好的提升缓存命中率。
可能回答牛头不对马嘴,只是分享这个思路,目前在应用开发中没写过sql,全是通过orm
同步到新浪微博
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。

我要回帖

更多关于 sql 当前季度 的文章

 

随机推荐