@(躍遷之路)專欄html
- 技術的精進不能只是簡單的刷題,而應該是不斷的「刻意」練習
- 該系列改版後正式歸入【躍遷之路】專欄,持續更新
題目描述mysql
DROP TABLE IF EXISTS test1
;
CREATE TABLE test1
(id
int(11) NOT NULL AUTO_INCREMENT,username
varchar(20) NOT NULL,course
varchar(20) NOT NULL,score
bigint(20) NOT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;sql
INSERT INTO test1
VALUES ('1', '張三', '數學', '34');
INSERT INTO test1
VALUES ('2', '張三', '語文', '44');
INSERT INTO test1
VALUES ('3', '張三', '英語', '54');
INSERT INTO test1
VALUES ('4', '李四', '數學', '134');
INSERT INTO test1
VALUES ('5', '李四', '語文', '144');
INSERT INTO test1
VALUES ('6', '李四', '英語', '154');
INSERT INTO test1
VALUES ('7', '王五', '數學', '234');
INSERT INTO test1
VALUES ('8', '王五', '語文', '244');
INSERT INTO test1
VALUES ('9', '王五', '英語', '254');函數
查出如下結果
spa
法1.net
SELECT A.username,A.score as '數學',B.score as '語文',C.score as '英語' FROM (select username,course,score from test1 where course = '數學') A, (select username,course,score from test1 where course = '語文') B, (select username,course,score from test1 where course = '英語') C WHERE A.username = B.username and B.username = C.username
法2【推薦】code
select username,sum(case course when '數學' then score else 0 end ) as '數學', sum(case course when '語文' then score else 0 end ) as '語文', sum(case course when '英語' then score else 0 end ) as '英語' FROM test1 group by username
題目描述sqlite
在audit表上建立外鍵約束,其emp_no對應employees_test表的主鍵id。
CREATE TABLE employees_test(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
);htm
CREATE TABLE audit(
EMP_no INT NOT NULL,
create_date datetime NOT NULL
);blog
DROP TABLE audit; CREATE TABLE audit( EMP_no INT NOT NULL, create_date datetime NOT NULL, FOREIGN KEY(EMP_no) REFERENCES employees_test(ID) );
因爲視圖 emp_v 的記錄是從 employees 中導出的,因此要判斷二者中相等的數據,只須要判斷emp_no相等便可。 方法一:用 WHERE 選取兩者 emp_no 相等的記錄 SELECT em.* FROM employees AS em, emp_v AS ev WHERE em.emp_no = ev.emp_no 方法二:用 INTERSECT 關鍵字求 employees 和 emp_v 的交集 可參考:http://www.sqlite.org/lang_select.html SELECT * FROM employees INTERSECT SELECT * FROM emp_v 方法三:仔細一想,emp_v的所有記錄均由 employees 導出,所以能夠投機取巧,直接輸出 emp_v 全部記錄 SELECT * FROM emp_v 【錯誤方法:】用如下方法直接輸出 *,會獲得兩張表中符合條件的重複記錄,所以不合題意,必須在 * 前加表名做限定 SELECT * FROM employees, emp_v WHERE employees.emp_no = emp_v.emp_no
題目描述
將全部獲取獎金的員工當前的薪水增長10%。
create table emp_bonus(
emp_no int not null,
recevied datetime not null,
btype smallint not null);
CREATE TABLE salaries
(emp_no
int(11) NOT NULL,salary
int(11) NOT NULL,from_date
date NOT NULL,to_date
date NOT NULL, PRIMARY KEY (emp_no
,from_date
));
UPDATE salaries SET salary = salary * 1.1 WHERE emp_no IN (SELECT s.emp_no FROM salaries AS s INNER JOIN emp_bonus AS eb ON s.emp_no = eb.emp_no AND s.to_date = '9999-01-01')
題目描述
針對庫中的全部表生成select count(*)對應的SQL語句
CREATE TABLE employees
(emp_no
int(11) NOT NULL,birth_date
date NOT NULL,first_name
varchar(14) NOT NULL,last_name
varchar(16) NOT NULL,gender
char(1) NOT NULL,hire_date
date NOT NULL,
PRIMARY KEY (emp_no
));
create table emp_bonus(
emp_no int not null,
recevied datetime not null,
btype smallint not null);
CREATE TABLE dept_emp
(emp_no
int(11) NOT NULL,dept_no
char(4) NOT NULL,from_date
date NOT NULL,to_date
date NOT NULL,
PRIMARY KEY (emp_no
,dept_no
));
CREATE TABLE dept_manager
(dept_no
char(4) NOT NULL,emp_no
int(11) NOT NULL,from_date
date NOT NULL,to_date
date NOT NULL,
PRIMARY KEY (emp_no
,dept_no
));
CREATE TABLE salaries
(emp_no
int(11) NOT NULL,salary
int(11) NOT NULL,from_date
date NOT NULL,to_date
date NOT NULL,
PRIMARY KEY (emp_no
,from_date
));
輸出格式:
cnts
select count(*) from employees;
select count(*) from departments;
select count(*) from dept_emp;
select count(*) from dept_manager;
select count(*) from salaries;
select count(*) from titles;
select count(*) from emp_bonus;
本題主要有如下兩個關鍵點: 一、在 SQLite 系統表 sqlite_master 中能夠得到全部表的索引,其中字段 name 是全部表的名字,並且對於本身建立的表而言,字段 type 永遠是 'table',詳情可參考: http://blog.csdn.net/xingfeng0501/article/details/7804378 二、在 SQLite 中用 「||」 符號鏈接字符串 SELECT "select count(*) from " || name || ";" AS cnts FROM sqlite_master WHERE type = 'table' 3.mysql使用concat進行字符串拼接
題目描述
獲取Employees中的first_name,查詢按照first_name最後兩個字母,按照升序進行排列
CREATE TABLE employees
(emp_no
int(11) NOT NULL,birth_date
date NOT NULL,first_name
varchar(14) NOT NULL,last_name
varchar(16) NOT NULL,gender
char(1) NOT NULL,hire_date
date NOT NULL,
PRIMARY KEY (emp_no
));
輸出格式:
first_name
Chirstian
Tzvetan
Bezalel
Duangkaew
Georgi
Kyoichi
Anneke
Sumant
Mary
Parto
Saniya
本題考查 substr(X,Y,Z) 或 substr(X,Y) 函數的使用。其中X是要截取的字符串。Y是字符串的起始位置(注意第一個字符的位置爲1,而不爲0),取值範圍是±(1~length(X)),當Y等於length(X)時,則截取最後一個字符;當Y等於負整數-n時,則從倒數第n個字符處截取。Z是要截取字符串的長度,取值範圍是正整數,若Z省略,則從Y處一直截取到字符串末尾;若Z大於剩下的字符串長度,也是截取到字符串末尾爲止。 SELECT first_name FROM employees ORDER BY substr(first_name,length(first_name)-1) SELECT first_name FROM employees ORDER BY substr(first_name,-2)
本題要用到SQLite的聚合函數group_concat(X,Y),其中X是要鏈接的字段,Y是鏈接時用的符號,可省略,默認爲逗號。此函數必須與 GROUP BY 配合使用。此題以 dept_no 做爲分組,將每一個分組中不一樣的emp_no用逗號鏈接起來(便可省略Y)。可參考: http://www.sqlite.org/lang_aggfunc.html#groupconcat http://blog.csdn.net/langzxz/article/details/16807859 SELECT dept_no, group_concat(emp_no) AS employees FROM dept_emp GROUP BY dept_no
本題邏輯有問題,在挑選當前最大、最小salary時沒加 to_date = '9999-01-01' 做條件限制,致使挑選出來的是全表最大、最小salary,而後對除去這兩個salary再做條件限制 to_date = '9999-01-01' ,求平均薪水,此時求出的平均薪水與題目邏輯要求的不一樣。 SELECT AVG(salary) AS avg_salary FROM salaries WHERE to_date = '9999-01-01' AND salary NOT IN (SELECT MAX(salary) FROM salaries) AND salary NOT IN (SELECT MIN(salary) FROM salaries) 正確的邏輯應以下所示,但在本題OJ系統中通不過: SELECT AVG(salary) AS avg_salary FROM salaries WHERE to_date = '9999-01-01' AND salary NOT IN (SELECT MAX(salary) FROM salaries WHERE to_date = '9999-01-01') AND salary NOT IN (SELECT MIN(salary) FROM salaries WHERE to_date = '9999-01-01')
題目描述
分頁查詢employees表,每5行一頁,返回第2頁的數據
CREATE TABLE employees
(emp_no
int(11) NOT NULL,birth_date
date NOT NULL,first_name
varchar(14) NOT NULL,last_name
varchar(16) NOT NULL,gender
char(1) NOT NULL,hire_date
date NOT NULL,
PRIMARY KEY (emp_no
));
select * from employees limit 5,5
本題用 EXISTS 關鍵字的方法以下:意爲在 employees 中挑選出令(SELECT emp_no FROM dept_emp WHERE emp_no = employees.emp_no)不成立的記錄,即當 employees.emp_no=10011時。反之,把NOT去掉,則輸出 employees.emp_no=10001~10010時的記錄。 SELECT * FROM employees WHERE NOT EXISTS (SELECT emp_no FROM dept_emp WHERE emp_no = employees.emp_no)