日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

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

發(fā)布時(shí)間:2025/5/22 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 R语言实战第一,二章SQL版 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
星辰大海

這是之前使用R語(yǔ)言完成的一道簡(jiǎn)單的數(shù)據(jù)統(tǒng)計(jì)題目鏈接:
https://zhuanlan.zhihu.com/p/27092971

完成之后心理還是有點(diǎn)小得意的。但和答案一對(duì)比就發(fā)現(xiàn)問(wèn)題了,自己的計(jì)算數(shù)據(jù)和正確結(jié)果差距太大了。看來(lái)我用語(yǔ)言暫時(shí)還是很難保證數(shù)據(jù)計(jì)算的準(zhǔn)確性, 所以有了這篇,畢竟SQL語(yǔ)句更熟悉一些。

環(huán)境準(zhǔn)備

要使用SQL查詢(xún)自然要先有數(shù)據(jù)庫(kù)了,有了docker技術(shù)后,我就不太傾向于直接在電腦上安裝軟件了,所以這次要先將MySQL在docker中啟動(dòng)起來(lái)。我使用的是Mac,docker的安裝就不贅述了,直接總官網(wǎng)下載就可以了,目前Mac已經(jīng)不在使用boot2docker了,號(hào)稱(chēng)是原生docker,但經(jīng)過(guò)這次實(shí)踐發(fā)現(xiàn),其實(shí)談不上原生,依舊是虛擬機(jī)方式實(shí)現(xiàn)的,只不過(guò)不再使用VirtualBox了,關(guān)于這點(diǎn)會(huì)在后面進(jìn)行解釋。接下來(lái)開(kāi)始操作。

先下載mysql的docker image

docker pull mysql:5.6

啟動(dòng)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

這時(shí)問(wèn)題就出現(xiàn)了, 以守護(hù)進(jìn)程形式啟動(dòng)mysql時(shí), 總是自動(dòng)退出, 而且按照docker提供的日志存儲(chǔ)目錄(/var/lib/docker)根本就找不到, 系統(tǒng)上就沒(méi)有這個(gè)目錄. 沒(méi)有日志又沒(méi)法定位問(wèn)題, 真是沒(méi)想到第一步就卡住了.

只好到網(wǎng)上搜索為什么Mac系統(tǒng)上沒(méi)有docker的日志目錄,找到了一些線索:Mac依舊使用虛擬機(jī)實(shí)現(xiàn)的docker,所有的文件都保存在一個(gè)虛擬機(jī)的鏡像文件里,"/var/lib/docker"其實(shí)是虛擬機(jī)中的目錄,所以在Mac上當(dāng)然找不到。但是也有辦法進(jìn)入虛擬機(jī)內(nèi)部查看目錄結(jié)構(gòu):

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

接下來(lái)就比較分析問(wèn)題了,mysql沒(méi)能啟動(dòng)的主要原因還是docker run命令的參數(shù)順序問(wèn)題, 調(diào)整一下就好了。

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

導(dǎo)入數(shù)據(jù)

MySQL終于啟動(dòng)成功了,接下來(lái)就要倒入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文件的語(yǔ)句:

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`);

查詢(xún)注冊(cè)90天內(nèi)購(gòu)買(mǎi)的用戶數(shù)量

查詢(xún)注冊(cè)用戶數(shù)量, 并刪除注冊(cè)日期為'0000-00-00'的項(xiàng).

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

查詢(xún)注冊(cè)90天內(nèi)購(gòu)買(mǎi)的用戶數(shù)量。
這里需要注意一點(diǎn)MySQL的日期計(jì)算最好不要直接使用算數(shù)運(yùn)算,在這個(gè)語(yǔ)句前使用的是
and (p.purchase.date - u.signup.date) <= 90
結(jié)果計(jì)算的數(shù)量就比實(shí)際的數(shù)量少了很多,目前還不確定造成這個(gè)現(xiàn)象的原因,總之盡量是用date的計(jì)算函數(shù)。

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'

在進(jìn)行用戶表,購(gòu)買(mǎi)表和短信消息表的聯(lián)合查詢(xún)時(shí),查詢(xún)時(shí)長(zhǎng)超過(guò)了30s,MySQL報(bào)錯(cuò):

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

我使用的是MySQL WorkBench,發(fā)現(xiàn)可以通過(guò)設(shè)置修改查詢(xún)的超時(shí)時(shí)長(zhǎng),按照下面這個(gè)答案修改超時(shí)時(shí)長(zhǎng)為3000s:
https://stackoverflow.com/questions/2698401/how-to-store-mysql-query-results-in-another-table

修改后依舊查詢(xún)超慢,可能是因?yàn)椴樵?xún)?nèi)鄙賰?yōu)化,而且同時(shí)查詢(xún)?nèi)龔埍?#xff0c;導(dǎo)致速度緩慢,優(yōu)化的方法,可以將上一步用戶表和購(gòu)買(mǎi)表的聯(lián)合查詢(xún)結(jié)果先保存到一個(gè)中間表,然后將查詢(xún)條件建好索引,之后再?lài)L試。但是這次使用讓我感覺(jué)是R確實(shí)在速度上比MySQL要快一些。

以下是使用三表聯(lián)合查詢(xún)的語(yǔ)句,真是慢的要死,幾十分鐘都沒(méi)有響應(yīng)。后來(lái)實(shí)在是沒(méi)有辦法,只能查詢(xún)正在進(jìn)行的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`);

以下是創(chuàng)建新表,和將數(shù)據(jù)倒入新表,并創(chuàng)建索引的過(guò)程。

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表也要?jiǎng)?chuàng)建好索引: alter table messages add index `index_user_id` (`user.id`); alter table messages add index `index_message_date` (`message.date`);

查詢(xún)90天內(nèi)未購(gòu)用戶和收到短信的比例

創(chuàng)建一張新表,用于保存注冊(cè)90天內(nèi)未購(gòu)買(mǎi)的用戶信息。將users表中有,而user_purchase(保存注冊(cè)90天內(nèi)購(gòu)買(mǎi)的用戶信息)中沒(méi)有的行插入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`);

查詢(xún)收到的短信日期大于注冊(cè)日期,并且小于注冊(cè)日期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' 《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專(zhuān)家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

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

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。