SQL面試題記錄--附視頻講解

視頻路徑:https://www.bilibili.com/video/BV1WZ4y1H7Eh?from=search&seid=7586957027441999328

將給到原始數(shù)據(jù)入庫(已經(jīng)給到建表sql語句,只要執(zhí)行sql即可建表和插入數(shù)據(jù)),共三張表:

1、頁面訪問數(shù)據(jù):page_visit_test_201909。

2、點擊事件觸發(fā)數(shù)據(jù):event_visit_test_201909。

3、訂單數(shù)據(jù):order_test_201909。

題目:寫sql語句,統(tǒng)計:每個客戶,在簽約訂單前(不包含簽約的當(dāng)日),在每個頁面的訪問次數(shù),在每個點擊事件的觸發(fā)次數(shù)。

提示和說明:

1) 所統(tǒng)計的是:客戶在簽約(購買)投顧服務(wù)訂單之前所訪問的各個頁面的次數(shù)+在客戶在簽約(購買)投顧服務(wù)訂單之前所點擊的各個事件的次數(shù)。

2) 某人的頁面訪問次數(shù)的統(tǒng)計:在頁面訪問表(page_visit_test_201909)中的任意一條數(shù)據(jù),代表某客戶(“客戶編號”字段)在某日(“頁面訪問的時間”字段)訪問了某頁面(“訪問的頁面”字段)1次,計數(shù)為1。

3) 某人點擊事件次數(shù)的統(tǒng)計:在點擊事件表(event_visit_test_201909)中的任意一條數(shù)據(jù),代表某客戶(“客戶編號”字段區(qū)分)在某日(“事件發(fā)生時間”字段區(qū)分)點擊了某事件(“事件名稱”字段區(qū)分)1次,計數(shù)為1。

4) 最終展示將每個客戶訪問各頁面的次數(shù)和點擊各事件的次數(shù)同時展示在一個結(jié)果表中,展示形式如下圖所示:

5)? 上圖中最后一個字段“是否購買”的判斷條件是:如果在訂單數(shù)據(jù)中能夠找到對應(yīng)的客戶(編號),且“組合名稱”不為空,則代表該客戶簽約(購買)了投顧服務(wù)(產(chǎn)品)。

6) 如果遇到重復(fù)購買的人,則第一次購買前的行為數(shù)據(jù)為:9月1日至第一次購買前的行為數(shù)據(jù)(統(tǒng)計);第二次購買前的行為數(shù)據(jù)為:第一次購買和第二次購買之間用戶行為數(shù)據(jù)(統(tǒng)計);以此類推。

7) 上述sql完成后,需在mysql中能直接運行。

8) 提交的文檔中除sql語句外,將應(yīng)聘者跑出的結(jié)果截圖附上。

解答的過程

1. 探索page數(shù)據(jù)表的基本結(jié)構(gòu)

#初步看一眼

select * from page_visit_test_201909 limit 30;



2. 探索page有哪些頁面類型

#探索頁面類型

select `訪問的頁面`

from page_visit_test_201909

group by `訪問的頁面`;


3. 探索page有哪些時間

# 探索日期

select 頁面訪問時間

from page_visit_test_201909

group by 頁面訪問時間;

發(fā)現(xiàn)都是9月份的

4. 初步分類匯總這個界面

#匯總每種頁面的數(shù)量

select 客戶編號,

sum(if(訪問的頁面='互聯(lián)網(wǎng)投顧首頁', 1, 0)) as 互聯(lián)網(wǎng)投顧首頁,

sum(if(訪問的頁面='找投顧', 1, 0)) as 找投顧,

sum(if(訪問的頁面='投顧個人頁', 1, 0)) as 投顧個人頁,

sum(if(訪問的頁面='投顧組合評論頁', 1, 0)) as 投顧組合評論頁,

sum(if(訪問的頁面='投顧組合詳情頁', 1, 0)) as 投顧組合詳情頁,

sum(if(訪問的頁面='投顧觀點列表', 1, 0)) as 投顧觀點列表,

sum(if(訪問的頁面='投顧觀點評論頁', 1, 0)) as 投顧觀點評論頁,

sum(if(訪問的頁面='投顧觀點詳情頁', 1, 0)) as 投顧觀點詳情頁,

sum(if(訪問的頁面='選組合', 1, 0)) as 選組合

from page_visit_test_201909 p_table

group by 客戶編號;


5. 探索order表的基本結(jié)構(gòu)

select * from order_test_201909 limit 30;


6. 看看9月份之后發(fā)生多少真正的交易

# 探索9月份簽約的用戶

select * from

order_test_201909 o_table

where `簽約日期` > '2019-08-31' and `簽約日期` < '2019-10-01' -- 非9月份的不用考慮

and `組合名稱` is not null

order by 客戶姓名, 簽約日期;


7.嘗試不考慮重復(fù)的情況下,計算購買之前的page次數(shù)

# 先不考慮買兩次的情況

select

a.客戶姓名, a.簽約日期, a.客戶編號,

sum(if(b.訪問的頁面='互聯(lián)網(wǎng)投顧首頁' and b.`頁面訪問時間`<a.簽約日期, 1, 0)) as 互聯(lián)網(wǎng)投顧首頁

from

(select * from

order_test_201909 o_table

where `簽約日期` > '2019-08-31' and `簽約日期` < '2019-10-01' -- 非9月份的不用考慮

and `組合名稱` is not null

order by 客戶姓名, 簽約日期)? a? -- 有用的訂單信息

left join page_visit_test_201909 b -- 頁面信息

on a.客戶編號 = b.客戶編號

group by a.客戶編號,a.簽約日期;


8. order表怎樣標(biāo)記上一次的交易時間

# 怎么把上一次的時間也搞進(jìn)來

select

a.*,

if(@last_record_user_id=a.客戶編號, @last_record_date, '2019-08-31') as prev_sign_date,

1 as mailema,

@last_record_date:=a.簽約日期 as qianyueriqi_jilv,

@last_record_user_id:=a.客戶編號 as bianhao_jilv

from

order_test_201909 a, (select @last_record_date:='2019-08-31', @last_record_user_id:=null) b

where `簽約日期` > '2019-08-31' -- and `簽約日期` < '2019-10-01' -- 非9月份的不用考慮

and `組合名稱` is not null

order by 客戶編號, 簽約日期;


9. 最終解決問題。

# 最終答案

select

a.客戶姓名,

-- a.簽約日期,

-- a.客戶編號,

a.買了嗎,

sum(if(b.訪問的頁面='互聯(lián)網(wǎng)投顧首頁' and b.`頁面訪問時間`<a.簽約日期 and b.`頁面訪問時間`>=a.prev_sign_date, 1, 0)) as 互聯(lián)網(wǎng)投顧首頁,

sum(if(b.訪問的頁面='找投顧' and b.`頁面訪問時間`<a.簽約日期 and b.`頁面訪問時間`>=a.prev_sign_date, 1, 0)) as 找投顧,

sum(if(b.訪問的頁面='投顧個人頁' and b.`頁面訪問時間`<a.簽約日期 and b.`頁面訪問時間`>=a.prev_sign_date, 1, 0)) as 投顧個人頁,

sum(if(b.訪問的頁面='投顧組合評論頁' and b.`頁面訪問時間`<a.簽約日期 and b.`頁面訪問時間`>=a.prev_sign_date, 1, 0)) as 投顧組合評論頁,

sum(if(b.訪問的頁面='投顧組合詳情頁' and b.`頁面訪問時間`<a.簽約日期 and b.`頁面訪問時間`>=a.prev_sign_date, 1, 0)) as 投顧組合詳情頁,

sum(if(b.訪問的頁面='投顧觀點列表' and b.`頁面訪問時間`<a.簽約日期 and b.`頁面訪問時間`>=a.prev_sign_date, 1, 0)) as 投顧觀點列表,

sum(if(b.訪問的頁面='投顧觀點評論頁' and b.`頁面訪問時間`<a.簽約日期 and b.`頁面訪問時間`>=a.prev_sign_date, 1, 0)) as 投顧觀點評論頁,

sum(if(b.訪問的頁面='投顧觀點詳情頁' and b.`頁面訪問時間`<a.簽約日期 and b.`頁面訪問時間`>=a.prev_sign_date, 1, 0)) as 投顧觀點詳情頁,

sum(if(b.訪問的頁面='選組合' and b.`頁面訪問時間`<a.簽約日期 and b.`頁面訪問時間`>=a.prev_sign_date, 1, 0)) as 選組合

from

(select

a.*,

if(@last_record_user_id=a.客戶編號, @last_record_date, '2019-08-31') as prev_sign_date,

@last_record_date:=a.簽約日期 as qianyueriqi_jilv,

@last_record_user_id:=a.客戶編號 as bianhao_jilv,

1 as 買了嗎

from

order_test_201909 a, (select @last_record_date:='2019-08-31', @last_record_user_id:=null) b

where `簽約日期` > '2019-08-31'? -- and `簽約日期` < '2019-10-01' -- 非9月份的不用考慮

and `組合名稱` is not null

order by 客戶編號, 簽約日期)? a? -- 有用的訂單信息而且包含了上一次的信息

left join page_visit_test_201909 b -- 頁面信息

on a.客戶編號 = b.客戶編號

group by a.客戶編號,a.簽約日期;


工具的相關(guān)知識

navicat破解版的安裝

https://zhuanlan.zhihu.com/p/111880971

如果需要運行大的sql文本,需要右鍵數(shù)據(jù)庫來執(zhí)行:


數(shù)據(jù)的基本結(jié)構(gòu)

python基礎(chǔ)

1、請不要運行代碼,直接回答出以下代碼運行結(jié)果

1."4.0"==4#F

2.bool("1")? ? #T

3.bool("0")? ? #T

4.bool(-1) #t

5.bool("")#F

6.int("3.42")? #T

7."wrqq">"acd"#T

8."ttt"=="ttt "# F

(1)請總結(jié)bool(x),x為什么時出值為False

x是數(shù)值0,或者空對象或者空字符串時為False

(2) 第7問的字符串之間比較的是什么?

字典序

(3) 第6問存在什么問題?

報錯:ValueError: invalid literal for int() with base 10: '3.42'

2、請自己造數(shù)據(jù) 用append分別對 list、pd.Series 、 pd.DataFrame進(jìn)行操作。(變量名分別為a/b/c)

例如:

b = pd.Series()

b.append(pd.Series(1))

(1) 現(xiàn)在要求不同類型的append都需成功加入新數(shù)據(jù)到對應(yīng)變量當(dāng)中。

對于list

In [28]

list1 = [1,3,5,7,None];

list1

list1.append([22,44,66])

list1

Out[28]:

[1, 3, 5, 7, None, [22, 44, 66]]

list在append的時候會把后面的東西作為一個整體放在后面,而且append是直接修改原list

對于Series

In [20]:

s2 = pd.Series([12, 14,17])

s2

a = s.append(s2)

a

Out[20]:

0 ? ? 1.0

1 ? ? 3.0

2 ? ? 5.0

3 ? ? NaN

4 ? ? 6.0

5 ? ? 8.0

0 ?? 12.0

1 ?? 14.0

2 ?? 17.0

dtype: float64

Series的append是合并兩個Series,不會修改第一個Series,需要用一個新的變量來“接收”append之后的結(jié)果。

對于dataframe

In [14]:

df2

df1.append(df2)

Out[14]:

0123

02.132240-1.065565-0.272990-0.583156

1-0.187449-1.4677040.0092710.193308

2-1.173036-0.3377390.993527-0.173590

31.7100911.747361-0.0021460.599004

4-0.7135300.313513-1.738293-0.254594

50.5284460.370375-0.0212910.774840

00.7471800.328049-0.831812-1.385509

對于dataframe跟series類似。原來的df不會變,需要用一個新的變量接收返回值。

(2)問:他們之間有什么區(qū)別?

1.是否把新append進(jìn)來的元素作為一個整體

2.list就地修改,df和series不會就地修改

python進(jìn)階

3、如何用append實現(xiàn)DataFrame的拼接(有兩種方式),請舉例說明。

df1.append(df2)

df1.append(df2, ignore_index = True) #ignore_index的時候會自動分配新的index,忽略原來的index

4、如何查看python的變量內(nèi)存地址(或id)?比如 a = “123456”,此時 a的變量內(nèi)存地址是什么?

id(a) 可以查看,id(a)==id(b)表示他們指向的是同一個對象

5、多個變量如何引用同一個內(nèi)存地址?

如果是小整數(shù)【-5,256】,或者短字符串,那么兩個變量就會是同一個內(nèi)存地址。

感覺是編譯期間能算出來相同的對象就會被優(yōu)化使用同一個內(nèi)存地址;不能在編譯器算出來,需要運行時算出來的時候就不會指向同一個地址。


長字符串不會被優(yōu)化。

6、什么是可變對象?什么是不可變對象?哪些數(shù)據(jù)類型是可變對象,哪些是不可變對象?

https://blog.csdn.net/as480133937/article/details/87305247

可變對象:對象引用的內(nèi)存里面的東西不可以修改的,如int float string tupple

可變對象:對象引用的內(nèi)存可以被修改,如list? dict

7、結(jié)合上述知識點,請觀察 題目2的內(nèi)存地址變化情況,請輸出打印到本題。

list

series

dataframe

操作系統(tǒng)知識(選做)

1、什么是多進(jìn)程?為什么要用進(jìn)程?

多個程序之間,處理不同的事情,基本很少通信的時候一般都是多進(jìn)程。多進(jìn)程可以更充分的利用電腦資源。

2、什么是多線程?為什么要用線程?

內(nèi)存上下文都一樣,只是處理的時間線多了幾條。多線程是一般更充分的利用cpu時間。

3、它們之間區(qū)別是什么?

多線程的粒度更小,在內(nèi)存等資源上還是可以共享的。多進(jìn)程則隔離的更明顯。

4、什么時候用多進(jìn)程、什么時候用多線程?

彼此比較密切,需要頻繁通信的時候使用多線程比較合適。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容