1. 程式人生 > >mysql綜合練習(2018.10.11學習筆記)

mysql綜合練習(2018.10.11學習筆記)

USE testdb;

CREATE TABLE sch(
	id INT PRIMARY KEY,
	NAME VARCHAR(50) NOT NULL,
	glass VARCHAR(50) NOT NULL
);

INSERT INTO sch VALUES
(1,'xiaoming','glass1'),
(2,'xiaojun','glass2');

SELECT * FROM sch;

DESC sch;

DELIMITER //

-- 建立一個儲存函式用來統計表sch中的記錄數
CREATE FUNCTION count_sch()
RETURNS INT
RETURN(SELECT COUNT(*) FROM sch);
//


-- 建立一個儲存過程,通過呼叫儲存函式的方法來獲取表sch中的記錄數和sch表中id的和
CREATE PROCEDURE add_id(OUT COUNT INT)
BEGIN
	DECLARE itmp INT;
	DECLARE cur_id CURSOR FOR SELECT id FROM sch;
	DECLARE EXIT HANDLER FOR NOT FOUND CLOSE cur_id;	
	SELECT count_sch() INTO COUNT;
	SET @sum=0;
	OPEN cur_id;
	REPEAT
	FETCH cur_id INTO itmp;
	IF itmp < 10
		THEN SET @sum = @sum+itmp;
	END IF;
	UNTIL 0 END REPEAT;
	CLOSE cur_id;
END//


-- 寫個hello word的儲存過程和函式
CREATE PROCEDURE helloword()
SELECT 'hello word';
//

CREATE FUNCTION helloword1()
RETURNS VARCHAR(20)
RETURN (SELECT 'hello word');
//

-- 寫一個完整的包括引數、變數、變數賦值、條件判斷、update語句、select返回結果集的儲存過程
CREATE PROCEDURE plogin
(
    p_username CHAR(15),
    p_password CHAR(32),
    p_ip CHAR(18),
    p_logintime DATETIME
)
LABEL_PROC:
BEGIN   
 
    DECLARE v_uid MEDIUMINT(8);  
    DECLARE v_realpassword CHAR(32);     
    DECLARE v_nickname VARCHAR(30);    
    DECLARE v_oltime SMALLINT(6);      
   
    SELECT u.uid, u.password, f.nickname, u.oltime INTO v_uid, v_realpassword, v_nickname, v_oltime
    FROM cdb_members u INNER JOIN cdb_memberfields f ON f.uid = u.uid WHERE u.username = p_username;   
   
    IF (v_uid IS NULL) THEN
        SELECT 2 AS ErrorCode;
        LEAVE LABEL_PROC;
    END IF;
 
    IF (p_password <> v_realpassword) THEN
        SELECT 3 AS ErrorCode;
        LEAVE LABEL_PROC;
    END IF;
 
    UPDATE ipsp_userexpands SET lastloginip = p_ip, lastlogintime = p_logintime WHERE uid = v_uid;
 
    SELECT 0 AS ErrorCode, v_uid AS uid, v_nickname AS nickname, v_oltime AS oltime;
 
END LABEL_PROC //

-- 建立一個執行動態sql的儲存過程
CREATE PROCEDURE ipsp_getresourcedir
(
    p_hashcode CHAR(40)
)
LABEL_PROC:
BEGIN
    DECLARE v_sql VARCHAR(200);
    SET v_sql = CONCAT('SELECT filedir FROM ipsp_resources WHERE hashcode ='', p_hashcode, '' LIMIT 0, 1');
    SET @sql = v_sql;
    PREPARE sl FROM @sql;
    EXECUTE sl;
    DEALLOCATE PREPARE sl;
END LABEL_PROC //

-- 建立程式設計師工資表
CREATE TABLE proWage(
	id INT PRIMARY KEY AUTO_INCREMENT,
	PName CHAR(10),
	Wage INT
);//


-- 插入資料--
INSERT INTO ProWage(PName,Wage)VALUES('來稜',1700)//
INSERT INTO ProWage(PName,Wage)VALUES('張三',1200)//
INSERT INTO ProWage(PName,Wage)VALUES('李四',1800)//
INSERT INTO ProWage(PName,Wage)VALUES('二月',3500)//
INSERT INTO ProWage(PName,Wage)VALUES('藍天',2780)//

-- 建立一個儲存過程,對程式設計師的工資進行分析,月薪1500到10000不等,
-- 如果有百分之五十的人薪水不到2000元,給所有人加薪,每次加100,再
-- 進行分析,直到有一半以上的人大於2000元為止,儲存過程執行完後,最終加了多少錢? 

-- 1)建立儲存過程,查詢是否有一半程式設計師的工資在2200、3000、3500、4000、5000或6000元之上,
-- 如果不到分別每次給每個程式設計師加薪100元,至之一半程式設計師的工資達到2200,3000,3500,4000,
-- 5000或6000元。
CREATE PROCEDURE pw2(money INT)
BEGIN
	DECLARE sum1 INT; 
	DECLARE count1 INT;
	DECLARE num INT DEFAULT 0;
	DECLARE percent DOUBLE DEFAULT 0;
	REPEAT
		SELECT COUNT(*) INTO sum1 FROM proWage;
		SELECT COUNT(*) INTO count1 FROM proWage WHERE wage < money;
		SET percent := count1/sum1;
		IF percent >= 0.5 THEN
			UPDATE proWage SET wage := wage + 100;
			SET num := num + 1;
		END IF;	
	UNTIL percent < 0.5 END REPEAT;
	SELECT sum1;
	SELECT num;
	SELECT sum1 * num * 100;
END//	

-- 2)建立儲存過程,查詢程式設計師平均工資在4500元,如果不到則每個程式設計師每次加200元,
-- 至到所有程式設計師平均工資達到4500元。	
CREATE PROCEDURE pw3()
BEGIN
	DECLARE avg1 INT; 
	DECLARE num INT DEFAULT 0;
	REPEAT
		SELECT AVG(wage) INTO avg1 FROM proWage;
		IF avg1 < 4500 THEN
			UPDATE proWage SET wage := wage + 200;
			SET num := num + 1;
		END IF;	
	UNTIL avg1 > 4500 END REPEAT;
	SELECT num;
	SELECT (SELECT COUNT(*) FROM prowage) * num * 200;
END//		
		

CREATE TABLE Member  -- 學生表
(
	MID  CHAR(10) PRIMARY KEY,  -- 學生號
	MName  CHAR(50) NOT NULL  -- 姓名
)//

CREATE TABLE F  -- 課程表
(
	FID   CHAR(10) PRIMARY KEY,    -- 課程號
	FName  CHAR(50) NOT NULL -- 課程名
)//

CREATE TABLE score  -- 學生成績表
(
	SID INT PRIMARY KEY AUTO_INCREMENT,  -- 成績記錄號
	FID CHAR(10),     -- 課程號
	MID CHAR(10),     -- 學生號
	Score  INT NOT NULL,   -- 成績
	CONSTRAINT fk_score1 FOREIGN KEY(FID) REFERENCES F(FID),
	CONSTRAINT fk_score2 FOREIGN KEY(MID) REFERENCES Member(MID)
)//

-- 課程表中插入資料--
INSERT INTO F(FID,FName)VALUES('F001','語文');
INSERT INTO F(FID,FName)VALUES('F002','數學');
INSERT INTO F(FID,FName)VALUES('F003','英語');
INSERT INTO F(FID,FName)VALUES('F004','歷史');
-- 學生表中插入資料--
INSERT INTO Member(MID,MName)VALUES('M001','張薩');
INSERT INTO Member(MID,MName)VALUES('M002','王強');
INSERT INTO Member(MID,MName)VALUES('M003','李三');
INSERT INTO Member(MID,MName)VALUES('M004','李四');
INSERT INTO Member(MID,MName)VALUES('M005','陽陽');
INSERT INTO Member(MID,MName)VALUES('M006','虎子');
INSERT INTO Member(MID,MName)VALUES('M007','夏雪');
INSERT INTO Member(MID,MName)VALUES('M008','璐璐');
INSERT INTO Member(MID,MName)VALUES('M009','珊珊');
INSERT INTO Member(MID,MName)VALUES('M010','香奈兒');
-- 成績表中插入資料--
INSERT INTO Score(FID,MID,Score)VALUES('F001','M001',78);
INSERT INTO Score(FID,MID,Score)VALUES('F002','M001',67);
INSERT INTO Score(FID,MID,Score)VALUES('F003','M001',89);
INSERT INTO Score(FID,MID,Score)VALUES('F004','M001',76);
INSERT INTO Score(FID,MID,Score)VALUES('F001','M002',89);
INSERT INTO Score(FID,MID,Score)VALUES('F002','M002',67);
INSERT INTO Score(FID,MID,Score)VALUES('F003','M002',84);
INSERT INTO Score(FID,MID,Score)VALUES('F004','M002',96);
INSERT INTO Score(FID,MID,Score)VALUES('F001','M003',70);
INSERT INTO Score(FID,MID,Score)VALUES('F002','M003',87);
INSERT INTO Score(FID,MID,Score)VALUES('F003','M003',92);
INSERT INTO Score(FID,MID,Score)VALUES('F004','M003',56);
INSERT INTO Score(FID,MID,Score)VALUES('F001','M004',80);
INSERT INTO Score(FID,MID,Score)VALUES('F002','M004',78);
INSERT INTO Score(FID,MID,Score)VALUES('F003','M004',97);
INSERT INTO Score(FID,MID,Score)VALUES('F004','M004',66);
INSERT INTO Score(FID,MID,Score)VALUES('F001','M006',88);
INSERT INTO Score(FID,MID,Score)VALUES('F002','M006',55);
INSERT INTO Score(FID,MID,Score)VALUES('F003','M006',86);
INSERT INTO Score(FID,MID,Score)VALUES('F004','M006',79);
INSERT INTO Score(FID,MID,Score)VALUES('F002','M007',77);
INSERT INTO Score(FID,MID,Score)VALUES('F003','M008',65);
INSERT INTO Score(FID,MID,Score)VALUES('F004','M007',48);
INSERT INTO Score(FID,MID,Score)VALUES('F004','M009',75);
INSERT INTO Score(FID,MID,Score)VALUES('F002','M009',88);

-- 1)查詢各個學生語文、數學、英語、歷史課程成績,例如下表:
SELECT m.MName AS 姓名,
SUM(CASE F.FName WHEN '語文' THEN s.Score END) 語文, 
SUM(CASE F.FName WHEN '數學' THEN s.Score END) 數學, 
SUM(CASE F.FName WHEN '英語' THEN s.Score END) 英語, 
SUM(CASE F.FName WHEN '歷史' THEN s.Score END) 歷史 
FROM Score s INNER JOIN Member m ON s.mid = m.mid 
INNER JOIN F ON s.fid = f.fid GROUP BY m.MName;

-- 2)查詢四門課中成績低於70分的學生及相對應課程名和成績。
SELECT m.mname AS 姓名, f.fname AS 課程名, s.score AS 成績 
FROM Score s 
INNER JOIN Member m ON s.mid = m.mid 
INNER JOIN F ON s.fid = f.fid 
WHERE s.score < 70;

-- 3)統計各個學生參加考試課程的平均分,且按平均分數由高到底排序。
SELECT mname AS 姓名, AVG(score) AS 平均分 
FROM Score s 
INNER JOIN Member m ON s.mid = m.mid 
INNER JOIN F ON s.fid = f.fid 
GROUP BY 姓名
ORDER BY 平均分 DESC;

-- 4)建立儲存過程,分別查詢參加1、2、3、4門考試及沒有參加考試的學生名單,要求顯示姓名、學號。
CREATE PROCEDURE search(num INT)
BEGIN
	SELECT mname AS 姓名, m.mid AS 學號,COUNT(*) AS 參加考試數
	FROM Score s 
	INNER JOIN Member m ON s.mid = m.mid 
	INNER JOIN F ON s.fid = f.fid
	GROUP BY 姓名
	HAVING COUNT(*) = num;
END;//

CALL search(2);