最近開發的系統中有個在線諮詢功能。學生在前臺提交諮詢信息,教師能夠登陸後臺回覆諮詢。該功能設計是直接使用一張表,使用是否開始標識該條記錄是不是諮詢的開始,而後使用一個會話id標識是屬於一次諮詢,根據建立時間排序,最後就像聊天同樣。sql
後來遇到一個需求,就是須要查詢出指定教師回覆的諮詢信息的第一條問和第一條答。先查詢出全部開始的問,而後使用會話id內鏈接加子查詢。<!--more-->然而遇到的問題是教師可能有多條回答,若是直接使用mybaits返回一個list,而後再去取第一條不是不能夠。可是仍是想直接使用sql完成,通過一番查找找到:數據庫
row_number() over(partition by col1 ORDER BY col2 ASC )
(ps:以上問題若是有更好解決辦法的歡迎評論)sass
我將項目的數據庫表進行改造並插入數據函數
-- ---------------------------- -- Table structure for zxzx -- ---------------------------- CREATE TABLE "ZXZX" ( "ID" VARCHAR2(64 BYTE) NOT NULL , "CONSULT_ID" VARCHAR2(255 BYTE) NULL , "CONTENT" VARCHAR2(255 BYTE) NULL , "CREATE_DATE" DATE NULL , "IS_START" VARCHAR2(255 BYTE) NULL , "USER_ID" VARCHAR2(64 BYTE) NULL ) LOGGING NOCOMPRESS NOCACHE ; -- ---------------------------- -- Records of zxzx -- ---------------------------- INSERT INTO "ZXZX" VALUES ('12sassaasd', '12123123', '第一條問', TO_DATE('2018-03-14 21:09:26', 'YYYY-MM-DD HH24:MI:SS'), '1', '111'); INSERT INTO "ZXZX" VALUES ('213123qwewq', '12123123', '第一次回答第一條問', TO_DATE('2018-03-14 22:10:16', 'YYYY-MM-DD HH24:MI:SS'), '0', '001'); INSERT INTO "ZXZX" VALUES ('sasdass2342', '12123123', '第二次回答第一條問', TO_DATE('2018-03-14 22:11:07', 'YYYY-MM-DD HH24:MI:SS'), '0', '001'); INSERT INTO "ZXZX" VALUES ('23234wewer', '12123123', '第一條問追問', TO_DATE('2018-03-14 22:22:00', 'YYYY-MM-DD HH24:MI:SS'), '0', '111'); INSERT INTO "ZXZX" VALUES ('345', '12123123', '回答一條追問', TO_DATE('2018-03-14 23:12:55', 'YYYY-MM-DD HH24:MI:SS'), '0', '001'); INSERT INTO "ZXZX" VALUES ('234324', '334455', '第二條問', TO_DATE('2018-03-14 23:08:21', 'YYYY-MM-DD HH24:MI:SS'), '1', '111'); INSERT INTO "ZXZX" VALUES ('5623365', '334455', '回答第二條問', TO_DATE('2018-03-14 23:14:07', 'YYYY-MM-DD HH24:MI:SS'), '0', '001'); INSERT INTO "ZXZX" VALUES ('12314', '112233', '問問問', TO_DATE('2018-03-14 23:14:49', 'YYYY-MM-DD HH24:MI:SS'), '1', '111'); INSERT INTO "ZXZX" VALUES ('12342', '112233', '答答答', TO_DATE('2018-03-14 23:15:15', 'YYYY-MM-DD HH24:MI:SS'), '0', '002'); -- ---------------------------- -- Indexes structure for table zxzx -- ---------------------------- -- ---------------------------- -- Checks structure for table zxzx -- ---------------------------- ALTER TABLE "ZXZX" ADD CHECK ("ID" IS NOT NULL); -- ---------------------------- -- Primary Key structure for table zxzx -- ---------------------------- ALTER TABLE "ZXZX" ADD PRIMARY KEY ("ID");
這裏須要將user_id=001所回答的問題查詢出,也就是上圖紅框中的信息。spa
SELECT row_number() over(partition by consult_id ORDER BY create_date ASC ) as rn, id, consult_id , content, user_id , is_start, create_date FROM zxzx WHERE user_id = '001' AND is_start !='1'
select w.id, w.consult_id , w.content, w.user_id , w.is_start, w.create_date, h.id, h.consult_id , h.content, h.user_id , h.is_start, h.create_date from zxzx w inner join ( select * from( SELECT row_number() over(partition by consult_id ORDER BY create_date ASC ) as rn, id, consult_id , content, user_id , is_start, create_date FROM zxzx WHERE user_id = '001' AND is_start !='1' )where rn = 1 ) h on h.consult_id = w.consult_id where w.is_start = '1'
上面說到使用row_number() over()
函數獲取根據某個字段分組後的一條數據,這就有點像「去重」。在Oracle中還可使用distinct
來返回惟一值。設計
SELECT DISTINCT col FROM table_name
在使用關鍵字 distinct 的時候,主要是要知道其做用於單個字段和多個字段的時候是有區別的:code
row_number() over(partition by col1 ORDER BY col2 ASC )
row_number()函數用於給記錄進行標號,over()函數的做用是將表中的記錄進行分組和排序。語法相似上面:將表中的數據按照col1進行分組,按照col2排序。partition by:表示分組。該函數主要是根據分組進行排序以後而後取出第一條數據以實現「去重」排序
inner join on
:只顯示兩張表都匹配的結果;left join on
:以左邊的表爲基準,顯示出左表的所有字段和右表所匹配的字段,空的用null
表示;right join on
:與左外鏈接相反,右外鏈接會查詢出右表的全部字段,顯示左表與右表匹配的字段,空用null
表示;full join on
:顯示兩張表所有內容。