建设银行 商户网站打不开,网站优化设计公司,恩施网站建设xiduyun,jsp 响应式网站模板下载1. sqlite简介
sqlite是一款非常轻便小巧的数据库#xff0c;以C语言开发#xff0c;已流行了数十年#xff0c;据说是世界上部署最多的数据库。为什么是部署最多的呢#xff1f;因为它根本不需要数据库服务器#xff0c;且可以在任意设备、任意操作系统上部署。因此以C语言开发已流行了数十年据说是世界上部署最多的数据库。为什么是部署最多的呢因为它根本不需要数据库服务器且可以在任意设备、任意操作系统上部署。因此很多应用程序无论是Windows的、Linux的、Mac的、甚至嵌入式的它们都内嵌了sqlite数据库。可想而知就部署数量而言确实没什么数据库可以和它竞争。为什么它可以做到在任意设备任意操作系统上部署呢一是因为它的一个数据库就是一个单一的文件二是因为它的数据库程序是纯C写的只要编译好就可以运行在这些地方并且据说只有一个C文件。
sqlite的官网https://www.sqlite.org/index.htmlsqlite手册网站https://www.sqlitetutorial.net/
2. sqlite的安装
sqlite的安装特别简单。如果不想从源码编译的话直接下载二进制文件即可运行。 sqlite下载页面https://www.sqlite.org/download.html
本文以Windows为例因此下载 “Precompiled Binaries for Windows” 这下面的。 这下面有 sqlite-dll-win-x64-3440200.zip (1.24MB) 和 sqlite-tools-win-x64-3440200.zip (4.71MB) 这2个。我们只要下载后者即可。前面那个dll的可能是应用程序调用sqlite的API用的和本次实验无关。
下载完并解压之后我们在这个解压好的文件夹下可以看到 3 个exe文件而本次我们只需用到 sqlite3.exe.
3. 用sqlite制作对局记录管理
3.1 问题描述
有一些对局记录可以利用sqlite进行管理。这些对局记录很简单只包含日期、对手ID、结果这三个要素。而结果可以用1、-1、0来分别表示胜、负、平。 这些对局记录已写入csv文件样例 20231216.csv 如下
2023-12-16,57793,1
2023-12-16,41864,1
2023-12-16,41864,-13.2 表设计
根据以上所描述的对局记录的特点很容易地设计表 go_records 如下
CREATE TABLE go_records
(id INTEGER PRIMARY KEY AUTOINCREMENT,date DATE,player INT,result INT
);这里使用自增id是为了避免将来在删除某条记录时因存在其他三要素完全一致的记录而造成误删。
貌似设计好了但这里有一个问题将来我们可以利用 sqlite 的.import命令来导入csv文件时由于自增id的存在就会引起导入失败因为csv文件中没有自增id这一列。 怎么处理呢 笔者不是数据库专家没有想到特别好的办法。想到的一个办法是再创一张临时表先将csv导入到临时表再将临时表导入到上面的 go_records 表中。临时表不需要id而临时表导入到最终表的过程中因使用 INSERT INTO 语句从而可以实现自创并自增id.
临时表的设计如下
CREATE TABLE tmp_go_records
(date DATE,player INT,result INT
);而导入完csv文件之后将临时表再导入到 go_records 表中的语句如下
INSERT INTO go_records (date, player, result)
SELECT date,player,result FROM tmp_go_records;3.3 运行sqlite并导入csv文件
步骤如下:
运行 sqlite3 .\go.db 这是打开 go.db 文件记录的数据库。另一种运行方式如下
sqlite3
.open C:\users\Finix\sqlite3\go.db值得一提的是.help命令可以看到各个帮助选项。
创建临时表和最终表 这里将上面的语句拷贝过来以作为一份完整的步骤。
DROP TABLE IF EXISTS go_records;
DROP TABLE IF EXISTS tmp_go_records;CREATE TABLE go_records
(id INTEGER PRIMARY KEY AUTOINCREMENT,date DATE,player INT,result INT
);CREATE TABLE tmp_go_records
(date DATE,player INT,result INT
);导入已准备好的csv文件
.mode csv
.import ./records/20231216.csv tmp_go_records
.import ./records/20231215.csv tmp_go_records以上是导入了2天的csv数据。注意以上语句不能加分号否则无效但又不会报错。
运行sql将临时表导入最终表
INSERT INTO go_records (date, player, result)
SELECT date,player,result FROM tmp_go_records;备份数据库
如果不太放心一个数据库文件可以再备份一个。命令如下
.save go.db.bak退出sqlite
.exit3.4 一些有趣的SQL
这么一张只有4列的表(其中一列还是自增id)能有什么有趣的SQL呢
与多少棋手交过手
select count(distinct player) from go_records;某天下了多少盘
select count(*) from go_records where date in (2023-12-16);总胜率
# 总胜率
SELECT result,cnt, sum(cnt) over() as total_cnt,concat(round((cnt*100.0/sum(cnt) over()), 2), %) as rate
FROM (SELECT result, count(*) AS cnt FROM go_records GROUP BY result
) src;对特定棋手的胜率
select concat(round((select (select count(*) as cnt from go_records where player40040 and result0)*100.0/ (select count(*) as cnt from go_records where player40040) as rate), 2), %
);对每一位棋手的胜率
select * from (select player, result, cnt, sum(cnt) over(PARTITION BY player) as total_cnt, round((cnt*100.0/(sum(cnt) over(PARTITION BY player))), 2) rate,concat(round((cnt*100.0/(sum(cnt) over(PARTITION BY player))), 2), %) as percentfrom (select player, result, count(*) as cnt from go_records group by player, result) src
) final
where result 0
order by final.rate desc;同一棋手出现在不同的2天
select distinct src.player from ((select player from go_records where date2023-12-15) t1 inner join (select player from go_records where date2023-12-16) t2 on t1.playert2.player
) src;关于这最后一个问题如果是打印出同一棋手出现在不同的多天则按以上方法需写多个inner join这显然是不能扩展和无法接受的。笔者一时之间还没有想出特别好的SQL的解决方案留待以后的思考吧。
(END)