日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

R语言实战第一,二章SQL版

發布時間:2025/5/22 数据库 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 R语言实战第一,二章SQL版 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
星辰大海

這是之前使用R語言完成的一道簡單的數據統計題目鏈接:
https://zhuanlan.zhihu.com/p/27092971

完成之后心理還是有點小得意的。但和答案一對比就發現問題了,自己的計算數據和正確結果差距太大了。看來我用語言暫時還是很難保證數據計算的準確性, 所以有了這篇,畢竟SQL語句更熟悉一些。

環境準備

要使用SQL查詢自然要先有數據庫了,有了docker技術后,我就不太傾向于直接在電腦上安裝軟件了,所以這次要先將MySQL在docker中啟動起來。我使用的是Mac,docker的安裝就不贅述了,直接總官網下載就可以了,目前Mac已經不在使用boot2docker了,號稱是原生docker,但經過這次實踐發現,其實談不上原生,依舊是虛擬機方式實現的,只不過不再使用VirtualBox了,關于這點會在后面進行解釋。接下來開始操作。

先下載mysql的docker image

docker pull mysql:5.6

啟動mysql

docker run --name mysql -e MYSQL_ROOT_PASSWORD=mysql -d mysql:5.6 -p 3306:3306 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

這時問題就出現了, 以守護進程形式啟動mysql時, 總是自動退出, 而且按照docker提供的日志存儲目錄(/var/lib/docker)根本就找不到, 系統上就沒有這個目錄. 沒有日志又沒法定位問題, 真是沒想到第一步就卡住了.

只好到網上搜索為什么Mac系統上沒有docker的日志目錄,找到了一些線索:Mac依舊使用虛擬機實現的docker,所有的文件都保存在一個虛擬機的鏡像文件里,"/var/lib/docker"其實是虛擬機中的目錄,所以在Mac上當然找不到。但是也有辦法進入虛擬機內部查看目錄結構:

screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty

接下來就比較分析問題了,mysql沒能啟動的主要原因還是docker run命令的參數順序問題, 調整一下就好了。

docker run -d --name mysql -p 3306:3306 -v /Users/blackpiglet/Documents/big_data:/mnt/big_data -e MYSQL_ROOT_PASSWORD=mysql -e MYSQL_DATABASE=big_data mysql:5.6

導入數據

MySQL終于啟動成功了,接下來就要倒入csv文件,在倒入之前要先把表建好:

create table `users` (`user.id` varchar(100), `signup.date` DATE); create table `purchases` (`user.id` varchar(100), `purchase.date` DATE, `purchase.count` smallint); create table `messages` (`user.id` varchar(100), `message.date` DATE, `message.count` smallint);

倒入csv文件的語句:

LOAD DATA LOCAL INFILE '/mnt/big_data/users.csv'INTO TABLE `users`FIELDS TERMINATED BY ',' ENCLOSED BY '"'LINES TERMINATED BY '\n'IGNORE 1 LINES(`user.id`, `signup.date`);LOAD DATA LOCAL INFILE '/mnt/big_data/purchases.csv'INTO TABLE `purchases`FIELDS TERMINATED BY ',' ENCLOSED BY '"'LINES TERMINATED BY '\n'IGNORE 1 LINES(`user.id`, `purchase.date`, `purchase.count`);LOAD DATA LOCAL INFILE '/mnt/big_data/messages.csv'INTO TABLE `messages`FIELDS TERMINATED BY ',' ENCLOSED BY '"'LINES TERMINATED BY '\n'IGNORE 1 LINES(`user.id`, `message.date`, `message.count`);

查詢注冊90天內購買的用戶數量

查詢注冊用戶數量, 并刪除注冊日期為'0000-00-00'的項.

select count(*) from users where `signup.date` != '0000-00-00'; 23841SET SQL_SAFE_UPDATES = 0; delete from `users` where `signup.date` = '0000-00-00';

查詢注冊90天內購買的用戶數量。
這里需要注意一點MySQL的日期計算最好不要直接使用算數運算,在這個語句前使用的是
and (p.purchase.date - u.signup.date) <= 90
結果計算的數量就比實際的數量少了很多,目前還不確定造成這個現象的原因,總之盡量是用date的計算函數。

select count( distinct (u.`user.id`)), u.`signup.date`, p.`purchase.date`, p.`purchase.count` from users ujoin purchases p on p.`user.id` = u.`user.id`where (p.`purchase.date` - u.`signup.date`) >= 1and (p.`purchase.date` <= date_add(u.`signup.date`, INTERVAL 90 DAY));# count( distinct (u.`user.id`)), signup.date, purchase.date, purchase.count '6369', '2013-06-17', '2013-06-19', '1'

在進行用戶表,購買表和短信消息表的聯合查詢時,查詢時長超過了30s,MySQL報錯:

Error Code: 2013. Lost connection to MySQL server during query

我使用的是MySQL WorkBench,發現可以通過設置修改查詢的超時時長,按照下面這個答案修改超時時長為3000s:
https://stackoverflow.com/questions/2698401/how-to-store-mysql-query-results-in-another-table

修改后依舊查詢超慢,可能是因為查詢缺少優化,而且同時查詢三張表,導致速度緩慢,優化的方法,可以將上一步用戶表和購買表的聯合查詢結果先保存到一個中間表,然后將查詢條件建好索引,之后再嘗試。但是這次使用讓我感覺是R確實在速度上比MySQL要快一些。

以下是使用三表聯合查詢的語句,真是慢的要死,幾十分鐘都沒有響應。后來實在是沒有辦法,只能查詢正在進行的query,然后kill了。

select count( distinct (u.`user.id`)), u.`signup.date`, p.`purchase.date`, p.`purchase.count` from users ujoin purchases p on p.`user.id` = u.`user.id`join messages m on m.`user.id` = u.`user.id`where (p.`purchase.date` - u.`signup.date`) >= 1and (p.`purchase.date` <= date_add(u.`signup.date`, INTERVAL 90 DAY))and (m.`message.date` >= date_add(u.`signup.date`, INTERVAL 1 DAY))and (m.`message.date` < p.`purchase.date`);

以下是創建新表,和將數據倒入新表,并創建索引的過程。

create table `user_purchase` (`user.id` varchar(100), `signup.dae` DATE, `purchase.date` DATE, `purchase.count` smallint);insert into user_purchase select distinct(u.`user.id`), u.`signup.date`, p.`purchase.date`, p.`purchase.count` from users ujoin purchases p on p.`user.id` = u.`user.id`where (p.`purchase.date` - u.`signup.date`) >= 1and (p.`purchase.date` <= date_add(u.`signup.date`, INTERVAL 90 DAY));alter table user_purchase add index `index_user_id` (`user.id`); alter table user_purchase add index `index_signup_date` (`signup.date`); alter table user_purchase add index `index_purchase_date` (`purchase.date`);# 給messages表也要創建好索引: alter table messages add index `index_user_id` (`user.id`); alter table messages add index `index_message_date` (`message.date`);

查詢90天內未購用戶和收到短信的比例

創建一張新表,用于保存注冊90天內未購買的用戶信息。將users表中有,而user_purchase(保存注冊90天內購買的用戶信息)中沒有的行插入user_not_buy表。

create table user_not_buy (`user.id` varchar(100), `signup.date` DATE);insert into user_not_buy select * from users where users.`user.id` not in (select `user.id` from user_purchase );

給新表加上索引

select count(*) from user_not_buy; alter table user_not_buy add index `index_user_id` (`user.id`); alter table user_not_buy add index `index_signup_date` (`signup.date`);

查詢收到的短信日期大于注冊日期,并且小于注冊日期90天的記錄。

select count( distinct(u_n_b.`user.id`) ) from user_not_buy as u_n_bjoin messages m on u_n_b.`user.id` = m.`user.id`and (m.`message.date` >= date_add(u_n_b.`signup.date`, INTERVAL 1 DAY))and (m.`message.date` <= date_add(u_n_b.`signup.date`, INTERVAL 90 DAY));# count( distinct(u_n_b.`user.id`) ) '16363' 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的R语言实战第一,二章SQL版的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。