SQL練習題(4),持續更新中

聲明:所有題目均是百度搜索,再由自己整理出來的,並非自己出的題。

1. 用一條SQL 語句 查詢出每門課都大於80 分的學生姓名

name course score
張三 語文 81
張三 數學 75
李四 語文 76
李四 數學 90
王五 語文 81
王五 數學 100
王五 英語 90

解法一:

每門課都大於80分,也就是說學生的所有課的最小分數大於80分MIN(score)>80再根據名稱進行排序,HAVING在分組的後的結果種進行篩選

SELECT NAME FROM `testscore` GROUP BY NAME HAVING MIN(score)>80;

解法二:

先查出每個學生的姓名和每門課程的最小分的結果集

再在查出的結果集的基礎上查詢姓名,並使用大於80分的條件進行篩選

SELECT NAME FROM (
SELECT NAME, MIN(score) AS msc FROM `testscore` GROUP BY NAME) AS t1 
WHERE t1.msc>80;

解法三:

先查出有任一門課程分數小於80分的學生姓名的結果集

再排除掉上述結果集裏的姓名,便查出大於80分的學生姓名,需用DISTINCT去重

SELECT DISTINCT NAME FROM testscore WHERE NAME NOT IN (
SELECT NAME FROM `testscore` WHERE score<80);

解法四:

使用NOT EXISTS特性,不關心子查詢中的結果,

如果子查詢有返回記錄,那麼就排除當前記錄,

如果子查詢沒有返回記錄,那麼就輸出當前記錄。

SELECT DISTINCT NAME FROM testscore t1 WHERE NOT EXISTS (
SELECT * FROM testscore t2 WHERE t1.name=t2.name AND t2.score<80);

解法五:

將score<80作爲單獨的一列,滿足條件爲1,不滿足爲0

再通過相加可以得到和,滿足條件和=0也就是每一門分數都大於80纔會得0.

SELECT NAME FROM `testscore` GROUP BY NAME HAVING SUM(score<80)=0;

解法六:

查出所有記錄條數

查出大於80分的記錄條數

再使用兩個記錄條數比對,查兩個的並集

SELECT * FROM
(SELECT NAME,COUNT(1) AS c1 FROM `testscore` GROUP BY NAME) t1,
(SELECT NAME,COUNT(1) AS c2 FROM `testscore` WHERE score>80 GROUP BY NAME) t2
WHERE t1.name=t2.name AND t1.c1=t2.c2;

解法七:

1.與解法六思路類似,在分組的結果上使用每個學生的分數記錄條數和大於80分的記錄條數進行比較,相等則說明都每門課程大於80分。

SELECT NAME FROM `testscore` GROUP BY NAME HAVING COUNT(1)=SUM(IF (score>80,1,0));

解法八:

左連接查詢,通過連接表查詢出t2表中王五的數據爲null

再根據條件篩選出t2表中名字爲null的

SELECT DISTINCT t1.`name` FROM `testscore` AS t1

LEFT JOIN (SELECT * FROM `testscore` WHERE score<=80) AS t2

ON t1.name=t2.name

WHERE t2.name IS NULL;

(求最高分成績的學生信息)思路

-- 先找出最高分,查出來的結MAX(score)=100

SELECT MAX(score) FROM `testscore`

-- 再找出所有分數等於最高分的成績

SELECT * FROM `testscore` WHERE score=100

-- 然後兩條語句結合 (不相關子查詢)

SELECT * FROM `testscore` WHERE score=(SELECT MAX(score) FROM `testscore`);

(求 每個同學最高分的成績)

解法一:

SELECT NAME,MAX(score) FROM `testscore` GROUP BY NAME;

解法二:

相關子查詢:依賴外部查詢的數據,外部查詢每執行一次,子查詢就執行一次

SELECT * FROM `testscore` t1 WHERE t1.`score`=(
SELECT MAX(score) FROM `testscore` t2 WHERE t2.`name`=t1.`name`);

-- (求大於平均分的成績信息)

SELECT * FROM `testscore` WHERE score > (SELECT AVG(score) FROM `testscore`);

2. 現有學生表如下:

自動編號 學號 姓名 課程編號 課程名稱 分數

1 2005001 張三 0001 數學 69

2 2005002 李四 0001 數學 89

3 2005001 張三 0001 數學 69

刪除除了自動編號不同, 其他都相同的學生冗餘信息

delete tablename where 自動編號 not in (

    select min( 自動編號)
    from tablename
    group by 學號, 姓名, 課程編號, 課程名稱, 分數

)

 

3. 一個叫 team 的表,裏面只有一個字段name, 一共有4 條紀錄,分別是a,b,c,d, 對應四個球對,現在四個球對進行比賽,用一條sql 語句顯示所有可能的比賽組合

表自連結先求出多種比賽組合的笛卡爾積,

再用小於排除重複的項

select a.name, b.name

from team a, team b

where a.name < b.name

 

4. 請用SQL 語句實現:從TestDB 數據表中查詢出所有月份的發生額都比101 科目相應月份的發生額高的科目。

請注意:TestDB 中有很多科目,都有1~12月份的發生額。

AccID :科目代碼,Occmonth :發生額月份,DebitOccur :發生額。

數據庫名:JcyAudit ,數據集:Select * from TestDB

select a.*

from TestDB a,

    (select Occmonth, max(DebitOccur) as Debit101ccur

    from TestDB

    where AccID='101'

    group by Occmonth) b

where a.Occmonth = b.Occmonth and a.DebitOccur > b.Debit101ccur

 

5. 把 a表 的數據查詢出 b表的結果 (行轉列)

a表

year

month

amount

1991

1

1.1

1991

2

1.2

1991

3

1.3

1991

4

1.4

1992

1

2.1

1992

2

2.2

1992

3

2.3

1992

4

2.4

b表

year

m1

m2

m3

m4

1991

1.1

1.2

1.3

1.4

1992

2.1

2.2

2.3

2.4

解法一:子查詢

SELECT `year`, 
    (SELECT amount FROM amount m WHERE MONTH=1 AND m.year=amount.year) AS m1,
    (SELECT amount FROM amount m WHERE MONTH=2 AND m.year=amount.year) AS m2,
    (SELECT amount FROM amount m WHERE MONTH=3 AND m.year=amount.year) AS m3,
    (SELECT amount FROM amount m WHERE MONTH=4 AND m.year=amount.year) AS m4
FROM amount GROUP BY YEAR

解法二:CASE語句

SELECT `year`,
SUM(CASE WHEN `month`='1' THEN amount ELSE 0 END) m1,
SUM(CASE WHEN `month`='2' THEN amount ELSE 0 END) m2,
SUM(CASE WHEN `month`='3' THEN amount ELSE 0 END) m3,
SUM(CASE WHEN `month`='4' THEN amount ELSE 0 END) m4
FROM amount  GROUP BY `year` 

解法三:IF語句

SELECT `year`, 
SUM(IF(`month`='1',amount,0)) AS m1,
SUM(IF(`month`='2',amount,0)) AS m2,
SUM(IF(`month`='3',amount,0)) AS m3,
SUM(IF(`month`='4',amount,0)) AS m4
FROM amount GROUP BY `year`

6. 有表A,結構如下:

p_ID p_Num s_id

1 10 01

1 12 02

2 8 01

3 11 01

3 8 03

其中:p_ID爲產品ID,p_Num爲產品庫存量,s_id爲倉庫ID。

請用SQL語句實現將上表中的數據合併,合併後的數據爲:

p_ID s1_id s2_id s3_id

1 10 12 0

2 8 0 0

3 11 0 8

其中:s1_id爲倉庫1的庫存量,s2_id爲倉庫2的庫存量,s3_id爲倉庫3的庫存量。如果該產品在某倉庫中無庫存量,那麼就是0代替。

select p_id,

    sum(case when s_id=1 then p_num else 0 end) as s1_id,

    sum(case when s_id=2 then p_num else 0 end) as s2_id,

    sum(case when s_id=3 then p_num else 0 end) as s3_id

from myPro group by p_id

7.問題:請用一條SQL語句查詢出每個科目平均分最高的班級名稱

class表

classID className
1 一班
2 二班
3 三班
4 四班

score表

studentID name classID subject grade
STD001 張三 1 數學 85
STD002 李四 2 語文 90
STD003 小紅 1 數學 80
STD004 小明 3 語文 88
STD005 小花 3 語文 100
STD006 大黃 2 數學 90
STD007 大哥 2 數學 84
 SELECT  className,`subject`,MAX(average)

 FROM (

 SELECT `subject`, className, AVG(grade) AS average

 FROM score a, class b

 WHERE a.`classID`=b.`classID`

 GROUP BY a.classID,`subject`

) t1

GROUP BY `subject`

HAVING MAX(average);

 

8.請將下表圖1數據查詢到圖2的結果 (列轉行)

a表

Name

Chinese

Math

English

張三

85

92

87

李四

96

89

100

王五

91

83

98

  b表

name

course

score

張三

語文

85

張三

英語

87

張三

數學

92

李四

數學

89

李四

語文

96

李四

英語

100

王五

數學

83

王五

語文

91

王五

英語

98

SELECT * FROM (

SELECT NAME, '語文' AS course, Chinese AS score FROM asaa

UNION

SELECT NAME, '數學' AS course, math AS score FROM asaa

UNION

SELECT NAME, '英語' AS course, english AS score FROM asaa

) n

ORDER BY n.name,n.score

9.請將 a 表數據查詢到 b 表的結果 (行轉列)

a表

name

course

score

張三

語文

85

張三

英語

87

張三

數學

92

李四

數學

89

李四

語文

96

李四

英語

100

王五

數學

83

王五

語文

91

王五

英語

98

b表

Name

Chinese

Math

English

張三

85

92

87

李四

96

89

100

王五

91

83

98

-- 解法一:CASE語句
SELECT NAME,

SUM(CASE course WHEN '語文' THEN score ELSE 0 END) AS Chinese,

SUM(CASE course WHEN '數學' THEN score ELSE 0 END) AS Math,

SUM(CASE course WHEN '英語' THEN score ELSE 0 END) AS English

FROM score GROUP BY NAME;
-- 解法二:IF語句

SELECT NAME,

SUM(IF(course='語文',score,0)) AS Chinese,

SUM(IF(course='數學',score,0)) AS Math,

SUM(IF(course='英語',score,0)) AS English

FROM score GROUP BY NAME;

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章