[Cattle off the database SQL combat] 51 to 61 personal questions and answers

51. The search string '10, A, B 'comma', the number 'appears cnt.

-- 除去','之前字符长度
SELECT LENGTH('10,A,B') AS length_str;
-- 除去','之后字符长度
SELECT LENGTH(REPLACE('10,A,B', ',','')) AS length_only_str;
-- 逗号出现次数
SELECT (LENGTH('10,A,B') - LENGTH(REPLACE('10,A,B', ',',''))) AS cnt;

Running time: 17ms

Take up memory: 3408k

[Mysql] will be fixed compartment delimited string converted into the form of a plurality of rows of
length (tagids) -length (replace ( tagids, ',', '')) indicates how many punctuation tagsid containing that punctuation +1 He says tagids use "," the delimiter contains a number of elements, i.e., the number of labels.

52. Employees acquired in first_name, queries in the last two letters first_name, arranged in ascending

-- 使用substr(s,start,len)函数 截取first_name最后两个字母 并以此排序
SELECT DISTINCT first_name
FROM employees
ORDER BY SUBSTR(first_name, LENGTH(first_name)-1, 2);

Running time: 28ms

Take up memory: 6628k

  • In MySQL, you may also be used RIGHT (s, n) function
-- 使用RIGHT(s,n)函数 获取first_name最后两个字母 并以此进行排序
SELECT DISTINCT first_name
FROM employees
ORDER BY RIGHT(first_name, 2);

MySQL functions

  • RIGHT (s, n)
    after returning n characters string s
  • SUBSTR (s, start, len)
    taken from the start position of the string s length len substring
  • LENGTH (s) / CHAR_LENGTH (s )
    Returns the number of characters string s

53. summarized by dept_no, belong to the same department emp_no connected in the comma, and the results are given dept_no result employees out connection

-- group_concat()函数的基本使用
SELECT dept_no, group_concat(emp_no) AS employees
FROM dept_emp
GROUP BY dept_no

Running time: 18ms

Take up memory: 3300k

54. Find the average wage avg_salary exclude employees after the current maximum and minimum salary.

-- 选出最大、最小薪水 再排除
SELECT AVG(salary) AS avg_salary
FROM salaries AS s, (
    SELECT MAX(salary) AS max_sal, MIN(salary) AS min_sal  FROM salaries
) AS ms
WHERE to_date='9999-01-01' AND s.salary != ms.max_sal AND s.salary != ms.min_sal;

Running time: 18ms

Take up memory: 3548k

-- 以下方法更严谨 
-- 选取最值时 是在当前选择的 而不是全局 
-- 但过不了OJ审核。。。
SELECT AVG(salary) AS avg_salary
FROM salaries AS s, (
    SELECT MAX(salary) AS max_sal, MIN(salary) AS min_sal  
    FROM salaries
    WHERE to_date='9999-01-01'
) AS ms
WHERE to_date='9999-01-01' AND s.salary != ms.max_sal AND s.salary != ms.min_sal;

55. paging query the employees table, every 5 rows a return data on page 2

-- 使用limit来实现分页
-- 第一页 以5行为一页 0,1,2,3,4
SELECT * FROM employees LIMIT (1-1)*5,5;
-- 第二页  5,6,7,8,9
SELECT * FROM employees LIMIT (2-1)*5,5;

Running time: 27ms

Take up memory: 4564k

MySQL's performance and limit the use of paging query analysis and optimization

56. emp_no get all employees, department number and the corresponding bonus dept_no type btype and received, is not assigned a specific employee does not show

  • The call table table structure
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 `emp_bonus`(
    `emp_no` int NOT NULL,
    `recevied` datetime NOT NULL,
    `btype` smallint NOT NULL);
-- 因为没有分配的员工不显示 所以员工表只取dept_emp就行
-- 注意emp_bonus 以前所建立的表
SELECT de.emp_no, de.dept_no, eb.btype, eb.recevied
FROM dept_emp AS de
LEFT JOIN emp_bonus AS eb
ON de.emp_no=eb.emp_no;

Running time: 22ms

Take up memory: 3368k

57. containing the keyword exists to find all information that is not assigned a specific sector employees.

-- exists()就类似一个函数 
-- 输入de.emp_no 输出是否存在'e.emp_no=de.emp_no'等式成立 返回T/F
SELECT *
FROM employees AS e
WHERE NOT EXISTS (
    SELECT * 
    FROM dept_emp AS de 
    WHERE e.emp_no=de.emp_no
);

Running time: 20ms

Take up memory: 3320k

  • Methods NOT EXISTS keywords:
    Italian pick out employees in order (SELECT * FROM dept_emp WHERE emp_no = employees.emp_no) does not hold the record

EXISTS query on the appearance of a loop one by one, one for every view EXISTS conditional statement,
when EXISTS in the conditional statements can return records row (regardless of how many rows are, as long as the return), the conditions will be true, it returns the current loop to this record;
conversely if EXISTS conditional statement can not return in the rows, the current loop to this record is discarded,
EXISTS conditions as a bool condition , when to return a result set was true, the result can not return set was false.

58. Get the data row of employees, and these lines are also present in the emp_v. Note that you can not use the keyword intersect.

  • This is the title given pre-conditions
存在如下的视图:
create view emp_v as select * from employees where emp_no >10005;
  • As in the first 47 questions, the solution can be reviewed by OJ systems
-- 最直观的 emp_v只是在employees的基础上生成的
SELECT * FROM emp_v;

-- 使用where
SELECT em.*
FROM employees AS em, emp_v AS ev 
WHERE em.emp_no=ev.emp_no;

-- 使用连接 找交集
SELECT em.*
FROM employees AS em 
INNER JOIN emp_v AS ev 
ON em.emp_no=ev.emp_no;

59. There are bonuses of employees to obtain relevant information. Given emp_no, first_name, last_name, bonus type btype, corresponding to the current salary situation and salary bonus money bonus.

  • bonus type

    • 1 btype its prize money of 10% of salary salary,
    • btype 2 of its 20% salary bonus,
    • Other types of salaries are 30%.

The current salary represents to_date = '9999-01-01'

-- 获奖员工信息 在使用btype时,除于10.0 
-- 注意要除以10.0,如果除以10的话,结果的小数位会被舍去
SELECT e.emp_no, e.first_name, e.last_name, eb.btype, s.salary, (s.salary*eb.btype/10.0) AS bonus
FROM employees AS e 
INNER JOIN emp_bonus AS eb
ON e.emp_no=eb.emp_no
INNER JOIN salaries AS s 
ON eb.emp_no=s.emp_no AND s.to_date='9999-01-01';

Running time: 20ms

Take up memory: 3408k

-- 通过case when使用btype
SELECT e.emp_no, e.first_name, e.last_name, eb.btype, s.salary, (
    CASE eb.btype
        WHEN 1 THEN s.salary*0.1
        WHEN 2 THEN s.salary*0.2
        ELSE s.salary*0.3
    END) AS bonus
FROM employees AS e 
INNER JOIN emp_bonus AS eb
ON e.emp_no=eb.emp_no
INNER JOIN salaries AS s 
ON eb.emp_no=s.emp_no AND s.to_date='9999-01-01';

Running time: 21ms

Take up memory: 3300k

60. In accordance with the accumulated salary and running_total, where running_total for the first two cumulative salary of employees and others and so on.

Specific results are as follows Demo show.

Output formats:

emp_no salary running_total
10001 88958 88958
10002 72527 161485
10003 43311 204796
-- 通过group by定位当前计算的emp_no 分组内容为比其emp_no小的员工 然后进行累加
SELECT s1.emp_no, s1.salary, SUM(s2.salary)
FROM salaries AS s1, salaries AS s2
WHERE s1.to_date='9999-01-01' AND s2.to_date='9999-01-01'
AND s2.emp_no <= s1.emp_no
GROUP BY s1.emp_no, s1.salary;

Running time: 29ms

Take up memory: 3572k

-- 使用子查询 更加直观
SELECT s1.emp_no, s1.salary, 
    (SELECT SUM(s2.salary) 
    FROM salaries AS s2 
    WHERE s2.emp_no <= s1.emp_no AND s2.to_date = '9999-01-01') AS running_total 
FROM salaries AS s1 
WHERE s1.to_date = '9999-01-01' 
ORDER BY s1.emp_no;

Running time: 21ms

Take up memory: 3304k

  • Note: The above two methods, although there is no error in the actual environment, but too slow, do not cache the results of previous

  • Less use of temporary variables @persum efficient way to achieve the results 5ms (+ 2ms)
-- 使用@persum作为临时变量 存储上一次累加的薪水总额
SELECT s.emp_no, s.salary, (@persum:=@persum + s.salary) AS running_total
FROM salaries AS s, (SELECT @persum:=0) AS ps
WHERE s.to_date='9999-01-01'
ORDER BY s.emp_no;

61. For the employees table, the odd rows are given first_name

-- 获取排名为奇数的first_name
SELECT e1.first_name 
FROM (
    -- 得到每个first_name和它的排名  
    SELECT e2.first_name, (
        -- 对每个first_name进行排序编号 计数有多少排在它前面的  
        SELECT COUNT(*) 
        FROM employees_sample AS e3 
        WHERE e3.first_name <= e2.first_name) AS rowid 
     FROM employees_sample AS e2) AS e1
WHERE e1.rowid % 2 = 1;

Running time: 17ms

Take up memory: 3552k

-- 在where 直接判断计数是否为奇数 
SELECT eo.first_name
FROM employees_sample AS eo
WHERE (
    SELECT COUNT(*)
    FROM employees_sample AS ei
    WHERE ei.first_name <= eo.first_name
) % 2 = 1;
  • Use COUNT () function to do rankings

Complete personal practice code for

I practice SQL code has been uploaded to Github: https://github.com/slowbirdoflsh/newcode-sql-practice
for reference only ~ ~ ~

Guess you like

Origin www.cnblogs.com/slowbirdoflsh/p/11223461.html