1. 程式人生 > 實用技巧 >大資料第24天-子查詢-楊大偉

大資料第24天-子查詢-楊大偉

   1 cd /d D:\MyWork\MySQL\mysql-5.7.28-winx64\bin rem 目的是為了執行mysql.exe
   2 mysql -h127.0.0.1 -P3306 -uroot -p123456 rem 作用是為了讓客戶端能夠正確的連線伺服器
   3 mysql --host=127.0.0.1 --port=3306 --user=root --password=123456 world
   4 
   5 -- 檢視伺服器中有哪些資料庫
   6 show databases;
   7 
   8 -- 建立新的資料庫
   9 create database company;
10 11 -- 切換工作資料庫 12 use company; 13 14 -- 檢視當前資料庫中的表 15 show tables; 16 17 -- 匯入.sql檔案中的資料 18 source d:/company.sql; 19 20 -- 查看錶中的資料 21 select * from employees; 22 23 -- 練習 : 建立world資料庫, 並切換, 再匯入world.sql檔案中的資料到world庫. 24 create database world; 25 26 use world;
27 28 source d:/world.sql; 29 30 -- 丟棄資料庫 31 drop database company; 32 33 drop database world; 34 35 -- 檢視當前工作資料庫 36 select database(); 37 38 -- 檢視當前工作資料庫的版本 39 select version(); 40 41 -- 檢視伺服器所有引數 42 show variables; 43 44 -- 和字符集設定相關的引數 : 45 character_set_client | gbk
46 character_set_connection | gbk 47 character_set_database | utf8 48 character_set_filesystem | binary 49 character_set_results | gbk 50 character_set_server | utf8 51 character_set_system | utf8 52 53 -- 如果client,connection和result的設定不是gbk, 必須執行以下語句 54 55 -- 修改客戶端編碼 56 set names gbk; 57 58 資料庫結構 59 mysqld 伺服器 60 資料庫1(目錄形式) 61 表1 62 資料(記錄)1 63 資料(記錄)2 64 資料(記錄)3 65 .... 66 表2 67 表3 68 .... 69 70 資料庫2 71 ...... 72 73 -- 查看錶中資料 74 select * from 表名; 75 76 -- 查看錶結構 77 describe employees; 78 desc employees; 79 80 +----------------+--------------+------+-----+---------+----------------+ 81 | Field | Type | Null | Key | Default | Extra | 82 +----------------+--------------+------+-----+---------+----------------+ 83 | employee_id | int(6) | NO | PRI | NULL | auto_increment | 84 | first_name | varchar(20) | YES | | NULL | | 85 | last_name | varchar(25) | YES | | NULL | | 86 | email | varchar(25) | YES | | NULL | | 87 | phone_number | varchar(20) | YES | | NULL | | 88 | job_id | varchar(10) | YES | MUL | NULL | | 89 | salary | double(10,2) | YES | | NULL | | 90 | commission_pct | double(4,2) | YES | | NULL | | 91 | manager_id | int(6) | YES | | NULL | | 92 | department_id | int(4) | YES | MUL | NULL | | 93 +----------------+--------------+------+-----+---------+----------------+ 94 95 create table customer( 96 id int, 97 name varchar(20), 98 age int, 99 phone varchar(15), 100 birthday date 101 ); 102 103 insert into customer ( 104 id, 105 name, 106 age, 107 phone, 108 birthday 109 ) values ( 110 1, 111 '張三', 112 30, 113 '134234234', 114 '1992-5-8' 115 ); 116 117 insert into customer ( 118 id, 119 name, 120 age, 121 phone, 122 birthday 123 ) values ( 124 2, 125 '李四', 126 40, 127 '1599234234', 128 '1991-5-8' 129 ); 130 131 insert into customer ( 132 id, 133 name, 134 age, 135 phone, 136 birthday 137 ) values ( 138 3, 139 '王五', 140 50, 141 '135234234', 142 '1995-11-8' 143 ); 144 145 -- 更新記錄(修改資料) 146 -- 如果更新時不加where過濾, 會導致所有資料被修改 147 update customer set 148 name = '某人', 149 age = 10; 150 151 update customer set 152 name = '張三', 153 age = 30 154 where 155 id = 1; 156 157 -- 刪除記錄 158 -- 如果沒有where過濾, 會全部刪除. 159 delete from customer; 160 161 delete from customer 162 where id = 2; 163 164 165 DML 資料操縱語言. 166 insert C 167 select R 168 update U 169 delete D 170 171 +----------------+---------------------------------------------------------------------------------------+------+-----+---------+-------+ 172 | Field | Type | Null | Key | Default | Extra | 173 +----------------+---------------------------------------------------------------------------------------+------+-----+---------+-------+ 174 | Code | char(3) 國家程式碼 | NO | PRI | | | 175 | Name | char(52) 國家名稱 | NO | | | | 176 | Continent | enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') | NO | | Asia | | 177 | Region | char(26) 地區 | NO | | | | 178 | SurfaceArea | float(10,2) 國土面積m | NO | | 0.00 | | 179 | IndepYear | smallint(6) 獨立年 | YES | | NULL | | 180 | Population | int(11) 國家人口 | NO | | 0 | | 181 | LifeExpectancy | float(3,1) 平均壽命 | YES | | NULL | | 182 | GNP | float(10,2) 國民生產總值 | YES | | NULL | | 183 | GNPOld | float(10,2) | YES | | NULL | | 184 | LocalName | char(45) | NO | | | | 185 | GovernmentForm | char(45) 政府組織 | NO | | | | 186 | HeadOfState | char(60) 領導人 | YES | | NULL | | 187 | Capital | int(11) 首都 | YES | | NULL | | 188 | Code2 | char(2) | NO | | | | 189 +----------------+---------------------------------------------------------------------------------------+------+-----+---------+-------+ 190 city 191 +-------------+----------+------+-----+---------+----------------+ 192 | Field | Type | Null | Key | Default | Extra | 193 +-------------+----------+------+-----+---------+----------------+ 194 | ID | int(11) | NO | PRI | NULL | auto_increment | 195 | Name | char(35) | NO | | | | 196 | CountryCode | char(3) | NO | MUL | | | 197 | District | char(20) | NO | | | | 198 | Population | int(11) | NO | | 0 | | 199 +-------------+----------+------+-----+---------+----------------+ 200 SELECT * 201 FROM departments; 202 203 SELECT department_id, location_id 204 FROM departments; 205 206 select 207 code, 208 name, 209 continent 210 from 211 country; 212 213 select 214 continent, 215 name, 216 code 217 from 218 country; 219 220 SQL注意點 : 221 SQL 語言大小寫不敏感。 222 SQL 可以寫在一行或者多行 223 關鍵字不能被縮寫也不能分行 224 各子句一般要分行寫。 225 使用縮排提高語句的可讀性。 226 227 -- 查詢國家的人口,名稱和程式碼及首都. 228 select 229 population, 230 name, 231 code, 232 capital 233 from 234 country; 235 236 -- AS用於給列起別名, AS關鍵字可以省略 237 SELECT last_name AS name, commission_pct comm 238 FROM employees; 239 240 -- 別名可以使用""包圍, 目的是讓它能原樣顯示或包含特殊的符號 241 select 242 code 國家程式碼, 243 name, 244 continent as "國家 大洲" 245 from 246 country; 247 248 -- 過濾行 where 條件布林 : 工作流程就是從基本表中測試每行資料, 都經過條件布林測試一下, 如果結果為真留下, 為假則丟棄. 249 SELECT employee_id, last_name, job_id, department_id 250 FROM employees 251 WHERE department_id = 90 ; 252 253 -- 查詢所有亞洲國家 254 select 255 code, 256 population, 257 name 258 from 259 country 260 where 261 continent = 'asia'; 262 263 -- 查詢所有亞洲國家 , 下面的SQL是錯誤的, where中不可以使用列的別名, 因為where先執行. 264 select 265 code, 266 population, 267 name, 268 continent cont 269 from 270 country 271 where 272 cont = 'asia'; 273 274 執行順序 : from => where => select 275 276 --查詢所有中國城市的人口和名稱和id號和國家程式碼, 給國家程式碼起別名, 嘗試在where中使用別名. 277 select 278 population, 279 name, 280 id, 281 countrycode code 282 from 283 city 284 where 285 countrycode = 'chn'; 286 287 -- between a and b --等效於salary >= a && salary <= 3500 288 SELECT last_name, salary 289 FROM employees 290 WHERE salary BETWEEN 2500 AND 3500; 291 292 -- id in(a, b, c) -- 等效於id = a || id = b || id = c 293 SELECT employee_id, last_name, salary, manager_id 294 FROM employees 295 WHERE manager_id IN (100, 101, 201); 296 297 select 298 code, 299 continent, 300 name, 301 population 302 from 303 country 304 where 305 name like 'china'; -- name = 'china' 如果模糊查詢中的字串沒有萬用字元, 和=效果一樣. 306 307 SELECT first_name 308 FROM employees 309 WHERE first_name LIKE 'S%'; 310 311 % 代表任意個任意字元 312 _ 代表一個任意字元 313 -- 查詢國家名稱中只要包含ch的都行 314 315 select 316 code, 317 population, 318 name, 319 continent 320 from 321 country 322 where 323 name like '%ch%' 324 325 -- 名字中第3個和第4個是in的國家 326 select 327 code, 328 population, 329 name, 330 continent 331 from 332 country 333 where 334 name like '__in%' 335 336 -- 查詢城市表中, 名稱的第2個和3個字母是or的城市. 337 select 338 id, 339 name, 340 countrycode 341 from 342 city 343 where 344 name like '_or%'; 345 346 -- 檢視哪些國家沒有首都 347 -- null和任意的比較運算, 結果一定是false, 處理null, 必須使用特殊的is來判斷 348 -- null值在進行統計時會被自動忽略. 349 select 350 code, 351 name, 352 continent, 353 capital 354 from 355 country 356 where 357 capital = null; 358 359 select 360 code, 361 name, 362 continent, 363 capital 364 from 365 country 366 where 367 capital is null; 368 369 select 370 code, 371 name, 372 continent, 373 capital 374 from 375 country 376 where 377 capital is not null; 378 379 -- 哪些國家尚未獨立. 380 select 381 name, 382 code, 383 indepYear 384 from 385 country 386 where 387 indepYear is null; 388 389 390 SELECT 391 employee_id, last_name, job_id, salary 392 FROM employees 393 WHERE 394 salary >=10000 395 AND 396 job_id LIKE '%MAN%'; 397 398 399 SELECT 400 employee_id, last_name, job_id, salary 401 FROM employees 402 WHERE 403 salary >= 10000 404 OR 405 job_id LIKE '%MAN%'; 406 407 -- 查詢亞洲國家中人口大於5000萬的國家. 408 select 409 code, 410 name, 411 continent, 412 population 413 from 414 country 415 where 416 continent = 'asia' 417 and 418 population > 50000000; 419 420 -- 查詢中國的城市人口小於20萬的城市. 421 select 422 * 423 from 424 city 425 where 426 countrycode = 'chn' 427 and 428 population < 200000; 429 430 -- 去重 distinct, 後面的列最好是有重複資料的 431 select 432 distinct 433 continent, 434 region 435 from 436 country; 437 438 -- 檢視中國各有哪些不同的省. 439 select 440 distinct district 441 from 442 city 443 where 444 countrycode = 'chn'; 445 446 SELECT last_name, job_id, department_id, salary 447 FROM employees 448 ORDER BY salary asc; 449 450 SELECT last_name, job_id, department_id, salary 451 FROM employees 452 ORDER BY salary desc; 453 454 select 455 code, 456 name, 457 population pop 458 from 459 country 460 where 461 continent = 'asia' 462 order by 463 pop; 464 465 order by中可以使用列的別名, 原因是它最後執行 466 467 順序 : from => where => select => order by 468 469 470 SELECT last_name, department_id, salary 471 FROM employees 472 ORDER BY department_id asc, salary DESC; 473 474 -- 查詢亞洲人口最少的國家 475 select 476 code, 477 name, 478 continent, 479 population pop 480 from 481 country 482 where 483 continent = 'asia' 484 order by 485 pop desc; 486 487 -- 查詢山東省人口最多的城市 488 select 489 id, 490 name, 491 district, 492 population 493 from 494 city 495 where 496 countrycode = 'chn' 497 and 498 district = 'shandong' 499 order by 500 population 501 502 503 504 -- 多表聯接 : 會產生笛卡爾集 505 -- 為了學習, 建立簡單表 506 create table city2 507 select * from city where name='london'; 508 +------+--------+-------------+----------+------------+ 509 | ID | Name | CountryCode | District | Population | 510 +------+--------+-------------+----------+------------+ 511 | 456 | London | GBR | England | 7285000 | 512 | 1820 | London | CAN | Ontario | 339917 | 513 +------+--------+-------------+----------+------------+ 514 515 create table country2 516 select * from country where code in('gbr', 'can'); 517 +------+----------------+---------------+-----------------+-------------+-----------+------------+----------------+------------+------------+------------- 518 | Code | Name | Continent | Region | SurfaceArea | IndepYear | Population | LifeExpectancy | GNP | GNPOld | LocalName 519 +------+----------------+---------------+-----------------+-------------+-----------+------------+----------------+------------+------------+------------- 520 | CAN | Canada | North America | North America | 9970610.00 | 1867 | 31147000 | 79.4 | 598862.00 | 625626.00 | Canada 521 | GBR | United Kingdom | Europe | British Islands | 242900.00 | 1066 | 59623400 | 77.7 | 1378330.00 | 1296830.00 | United Kingd 522 +------+----------------+---------------+-----------------+-------------+-----------+------------+----------------+------------+------------+------------- 523 524 select * from city2, country2; 525 結果集中的絕大多數都是垃圾. 必須要過濾掉 526 +------+--------+-------------+----------+------------+------+----------------+---------------+-----------------+-------------+-----------+------------+-- 527 | ID | Name | CountryCode | District | Population | Code | Name | Continent | Region | SurfaceArea | IndepYear | Population | L 528 +------+--------+-------------+----------+------------+------+----------------+---------------+-----------------+-------------+-----------+------------+-- 529 | 456 | London | GBR | England | 7285000 | CAN | Canada | North America | North America | 9970610.00 | 1867 | 31147000 | 530 | 1820 | London | CAN | Ontario | 339917 | CAN | Canada | North America | North America | 9970610.00 | 1867 | 31147000 | 531 | 456 | London | GBR | England | 7285000 | GBR | United Kingdom | Europe | British Islands | 242900.00 | 1066 | 59623400 | 532 | 1820 | London | CAN | Ontario | 339917 | GBR | United Kingdom | Europe | British Islands | 242900.00 | 1066 | 59623400 | 533 +------+--------+-------------+----------+------------+------+----------------+---------------+-----------------+-------------+-----------+------------+-- 534 535 select 536 * 537 from 538 city2, 539 country2 540 where 541 countrycode = code; 542 543 +------+--------+-------------+----------+------------+------+----------------+---------------+-----------------+-------------+-----------+------------+- 544 | ID | Name | CountryCode | District | Population | Code | Name | Continent | Region | SurfaceArea | IndepYear | Population | 545 +------+--------+-------------+----------+------------+------+----------------+---------------+-----------------+-------------+-----------+------------+- 546 | 1820 | London | CAN | Ontario | 339917 | CAN | Canada | North America | North America | 9970610.00 | 1867 | 31147000 | 547 | 456 | London | GBR | England | 7285000 | GBR | United Kingdom | Europe | British Islands | 242900.00 | 1066 | 59623400 | 548 +------+--------+-------------+----------+------------+------+----------------+---------------+-----------------+-------------+-----------+------------+- 549 550 -- 下面的SQL是錯誤的, 因為列名模糊 551 select 552 name, 553 population, 554 name, 555 continent, 556 population 557 from 558 city2, 559 country2 560 where 561 countrycode = code; 562 563 select 564 city2.name as cityName, 565 city2.population cityPop, 566 country2.name countryName, 567 country2.continent, 568 country2.population countryPop 569 from 570 city2, 571 country2 572 where 573 city2.countrycode = country2.code; 574 575 -- 表名的使用也麻煩了. 給表起別名 576 select 577 ci.name as cityName, 578 ci.population cityPop, 579 co.name countryName, 580 co.continent, 581 co.population countryPop 582 from 583 city2 as ci , 584 country2 co 585 where 586 ci.countrycode = co.code; 587 588 -- 表名一旦指定了別名, 原名就不可以使用了. 589 select 590 city2.name as cityName, 591 city2.population cityPop, 592 country2.name countryName, 593 country2.continent, 594 country2.population countryPop 595 from 596 city2 as ci, 597 country2 as co 598 where 599 city2.countrycode = country2.code; 600 601 -- 查詢所有國家的名稱和國家的首都的名稱. 602 select 603 co.name country, 604 ci.name captial, 605 co.population countryPop, 606 ci.population cityPop, 607 co.continent 608 from 609 country co, 610 city ci 611 where 612 co.capital = ci.id 613 614 -- where中有多個條件. 615 select 616 ci.name as cityName, 617 ci.population cityPop, 618 co.name countryName, 619 co.continent, 620 co.population countryPop 621 from 622 city2 as ci , 623 country2 co 624 where 625 ci.countrycode = co.code -- 聯接條件, 比普通過濾更重要. 626 and 627 ci.population > 1000000 628 629 +----------+---------+----------------+-----------+------------+ 630 | cityName | cityPop | countryName | continent | countryPop | 631 +----------+---------+----------------+-----------+------------+ 632 | London | 7285000 | United Kingdom | Europe | 59623400 | 633 +----------+---------+----------------+-----------+------------+ 634 635 SQL99標準中 內聯接不要用,號來寫, 而是使用專門的關鍵字join.... on 聯接條件 636 select 637 ci.name as cityName, 638 ci.population cityPop, 639 co.name countryName, 640 co.continent, 641 co.population countryPop 642 from 643 city2 as ci 644 inner join 645 country2 co 646 on 647 ci.countrycode = co.code 648 where 649 ci.population > 1000000; 650 651 -- on 和 where 效果相同, 但是下面的寫法不推薦 652 select 653 ci.name as cityName, 654 ci.population cityPop, 655 co.name countryName, 656 co.continent, 657 co.population countryPop 658 from 659 city2 as ci 660 inner join 661 country2 co 662 where 663 ci.countrycode = co.code 664 and 665 ci.population > 1000000; 666 667 -- on 和 where 效果相同, 但是下面的寫法不推薦 668 select 669 ci.name as cityName, 670 ci.population cityPop, 671 co.name countryName, 672 co.continent, 673 co.population countryPop 674 from 675 city2 as ci 676 inner join 677 country2 co 678 on 679 ci.countrycode = co.code 680 and 681 ci.population > 1000000; 682 683 -- 最好的寫法是下面的. inner關鍵字可以省略 684 select 685 ci.name as cityName, 686 ci.population cityPop, 687 co.name countryName, 688 co.continent, 689 co.population countryPop 690 from 691 city2 as ci 692 join 693 country2 co 694 on -- on後面只跟 聯接條件 695 ci.countrycode = co.code 696 where -- where 後面只跟 普通行過濾 697 ci.population > 1000000; 698 699 -- 查詢所有亞洲和歐洲國家的首都, 使用SQL99 700 select 701 co.name country, 702 co.continent, 703 ci.name capital 704 from 705 country co 706 join 707 city ci 708 on 709 co.capital = ci.id 710 where 711 co.continent in('asia', 'europe'); 712 713 -- 檢視所有國家名稱和首都及官方語言 714 select 715 co.name country, 716 co.continent, 717 ci.name capital, 718 cl.language 719 from 720 country co 721 join 722 city ci 723 on 724 co.capital = ci.id 725 join 726 countrylanguage cl 727 on 728 cl.countrycode = co.code 729 where 730 cl.isofficial = 't'; 731 732 -- 查詢簡單表的國家及首都 733 -- 內聯接的結果總是所有聯接條件為真的記錄. 為假的記錄全部濾掉. 734 select 735 co.name country, 736 ci.name capital, 737 ci.district 738 from 739 country2 co 740 join 741 city2 ci 742 on 743 co.capital = ci.id; 744 745 746 -- 外聯接可以保證某張表的資料完整, 即使聯接條件為假, 也要保留資料 747 select 748 co.name country, 749 ci.name capital, 750 ci.district 751 from 752 country2 co 753 left outer join 754 city2 ci 755 on 756 co.capital = ci.id; 757 758 select 759 co.name country, 760 ci.name capital, 761 ci.district 762 from 763 country2 co 764 right outer join 765 city2 ci 766 on 767 co.capital = ci.id; 768 769 -- 檢視所有國家名稱和首都, 即使沒有首都也要顯示. 770 select 771 co.name country, 772 co.continent, 773 ci.name capital 774 from 775 country co 776 left join 777 city ci 778 on 779 co.capital = ci.id; 780 781 -- 查詢哪些國家沒有首都 782 select 783 co.name country, 784 co.continent, 785 ci.name capital 786 from 787 country co 788 left join 789 city ci 790 on 791 co.capital = ci.id 792 where 793 ci.name is null; 794 795 // 虛擬碼 796 // 內聯接 797 Set leftTable; 798 Set rightTable; 799 Set resultSet = new Set(); 800 for (int i = 0; i < leftTable.length; i++) { 801 Row leftRow = leftTable[i]; 802 for (int j = 0; j < rightTable.length; j++) { 803 Row rightRow = rightTable[j]; 804 if (聯接條件(leftRow, rightRow)) { 805 Row newRow = leftRow + rightRow; 806 resultSet.add(newRow); 807 } 808 } 809 } 810 811 // 外聯接 812 Set leftTable; 813 Set rightTable; 814 Set resultSet = new Set(); 815 for (int i = 0; i < leftTable.length; i++) { 816 Row leftRow = leftTable[i]; 817 boolean flag = false; 818 for (int j = 0; j < rightTable.length; j++) { 819 Row rightRow = rightTable[j]; 820 if (聯接條件(leftRow, rightRow)) { 821 Row newRow = leftRow + rightRow; 822 resultSet.add(newRow); 823 flag = true; // 表明聯接條件為真的記錄儲存起來 824 } 825 } 826 827 if (!flag) { 828 Row newRow = leftRow + 空行(右表); 829 resultSet.add(newRow); 830 } 831 } 832 833 -- 查詢哪些國家沒有官方語言 834 select 835 co.name country, 836 cl.language, 837 cl.isofficial 838 from 839 country co 840 left join 841 countrylanguage cl 842 on 843 co.code = cl.countrycode 844 and 845 cl.isofficial = 'T' 846 where 847 cl.isofficial is null 848 849 -- 查詢所有國家的首都和官方語言, 沒有首都和官方語言的也要全部顯示. 850 851 -- 單行函式, 查詢結果中對每一行都單獨執行的函式 852 select 853 upper(name), 854 lower(continent) 855 from 856 county; 857 858 select 859 concat(code, name), 860 substr(name, 3, 2) 861 from 862 country; 863 864 -- 把國家的程式碼和名稱及大洲用@符號連線. 如 : CHN@China@asia 865 select 866 concat(concat(concat(concat(code, '@'), name), '@'), continent) 867 from 868 country; 869 870 select 871 concat(code, '@', name, '@', continent) 872 from 873 country; 874 875 876 -- 分組函式 : 作用於一組資料. 預設情況下虛表中的所有記錄被當作一個組. 877 分組函式都是統計運算, 特點就是一組資料只能有一個結果. 結果也必須是所有資料處理完後才有的. 878 879 max() 最大值 880 min() 最小值 881 avg() 平均值 882 sum() 求和 883 count() 計數 884 885 select 886 max(population), 887 min(surfacearea) 888 from 889 country ; 890 891 892 select 893 -- name, 不可以再把普通的列放在這裡 894 max(name), 895 max(population), 896 min(surfacearea) 897 from 898 country ; 899 900 複習 : 901 902 C / S 架構 903 Server : mysqld 904 Client : mysql 905 906 客戶端連線伺服器必須要提供 : 主機地址, 埠號, 使用者名稱, 密碼, 預設資料庫 907 mysql --host=127.0.0.1 --port=3306 --user=root --password=123456 world 908 909 -- 檢視所有資料庫 910 show databases; 911 912 -- 檢視庫中的表 913 show tables; 914 915 -- 檢視其他庫中的表 916 show tables from 庫名; 917 918 -- 查看錶結構 919 desc 表名; 920 921 -- 查看錶的建表語句 922 show create table 表名; 923 924 -- 通過建表語句可以看出表的儲存引擎, 預設字符集, 各種約束的名字.... 925 926 myisam引擎不支援高階特性 : 事務, 外來鍵, 行級鎖. 速度極快 927 innodb引擎支援高階特性, 速度稍慢. 928 929 ``的作用是專門用於包圍資料庫物件的名稱. 930 資料庫 931 932 933 索引 934 約束 935 函式 936 ...... 937 938 C : insert 939 R : select 940 U : update 941 D : delete 942 以上語句統稱為DML -> 資料操縱語言 943 944 945 create 946 drop 947 alter 948 以上語句統稱DDL語句 -> 資料定義語言 949 950 951 跨庫操作表 : 只需要在表名上加上庫.限定 952 select * from company.employees; 953 954 select 955 * 956 from 957 country; 958 959 使用使用者變數 960 set @var1 = 200; 961 set @var1 = 'abc'; 962 963 -- 查詢沒有首都和官方語言的國家 964 select 965 100, -- 常量 966 'abc', 967 20 + 30 / (50 - 3), -- 常量 968 @var1, -- 使用者變數 969 @@datadir, -- 系統變數 970 database(), -- 函式 971 now(), 972 co.*, -- 普通列 973 ci.*, 974 cl.* 975 from 976 country co 977 left join 978 city ci 979 on 980 co.capital = ci.id -- 聯接條件 981 left join 982 countrylanguage cl 983 on 984 co.code = cl.countrycode 985 and 986 cl.isofficial = 't' 987 where 988 cl.language is null 989 and 990 ci.name is null 991 order by 992 co.name desc; 993 994 995 -- 查詢亞洲國家的平均人口 996 select 997 avg(population) 998 from 999 country 1000 where 1001 continent = 'asia'; 1002 1003 -- 查詢全球平均壽命最高和最低 1004 select 1005 max(LifeExpectancy), 1006 min(LifeExpectancy) 1007 from 1008 country; 1009 1010 max() 最大值 1011 min() 最小值 1012 avg() 平均值 1013 sum() 求和 1014 count() 計數 1015 1016 select 1017 sum(population), 1018 count(capital) 1019 from 1020 country; 1021 1022 -- 查看錶中的記錄數 1023 select 1024 count(*) 1025 from 1026 country; 1027 1028 -- 解決的問題類似於, 檢視 各大洲 的情況. 1029 select 1030 continent, -- 群體概念 1031 max(name), 1032 avg(surfacearea) 1033 from 1034 country 1035 group by 1036 continent; 1037 1038 -- 檢視各地區的最大人口數 1039 select 1040 continent, 1041 region, 1042 max(population) 1043 from 1044 country 1045 group by 1046 continent, 1047 region; 1048 1049 select 1050 max(continent), 1051 region, 1052 max(population) 1053 from 1054 country 1055 group by 1056 region 1057 order by 1058 max(continent); 1059 1060 1061 -- 檢視各國的城市總人口數 1062 select 1063 countrycode, 1064 sum(population) 1065 from 1066 city 1067 group by 1068 countrycode 1069 1070 select 1071 name, 1072 population, 1073 sum(surfacearea) 1074 from 1075 country 1076 group by 1077 name, 1078 population; 1079 1080 -- 對分組的結果進行過濾, 只能使用having 1081 select 1082 countrycode, 1083 sum(population) sumPop 1084 from 1085 city 1086 group by 1087 countrycode 1088 having 1089 sumPop > 10000000 1090 order by 1091 sumPop; 1092 1093 -- 檢視亞洲國家各省城市總人口和城市個數中城市總人口數大於100萬的. 1094 select 1095 co.name, 1096 ci.district, 1097 sum(ci.population) sumPop, 1098 count(ci.id) cities 1099 from 1100 country co 1101 join 1102 city ci 1103 on 1104 co.code = ci.countrycode 1105 where 1106 co.continent = 'asia' 1107 group by 1108 co.name, 1109 ci.district 1110 having 1111 sumPop > 1000000 1112 order by 1113 cities desc; 1114 1115 解決SQL步驟 : 1116 1) 最基礎的基表, from 1117 2) 考慮一張表的資料夠不夠, 如果不夠進行連線 join 1118 3) 再考慮是外還是內, 如果是外還得考慮保證哪張表完整 1119 4) 有join必須要有on 1120 5) 是否需要對當前的大基表進行基礎的行過濾. where 1121 6) 是否需要分組, 分組依據的列是什麼. group by 1122 7) 如果有分組,第一時間,把分組的列放在 select 後面, 並同時繼續分析要選擇哪些列或統計運算. 1123 8) 是否要再對分組結果進行進一步過濾, 如果需要使用having 1124 9) 是否需要排序, 如果需要使用order by . 1125 1126 練習 : 1127 1 列出所有在超過10個國家中使用的語言。 1128 select 1129 language, 1130 count(countrycode) ct 1131 from 1132 countrylanguage 1133 group by 1134 language 1135 having 1136 ct > 10; 1137 1138 2 查詢每個大洲各有多少種政府組織形式和每個大洲最富有的收入 1139 select 1140 continent, 1141 count(distinct GovernmentForm), 1142 max(gnp) 1143 from 1144 country 1145 group by 1146 continent; 1147 1148 1149 3 列出不同的國家(country code)有居民超過7,000,000的城市, 它們有多少? 1150 select 1151 countrycode, 1152 count(*) 1153 from 1154 city 1155 where 1156 population > 7000000 1157 group by 1158 countrycode; 1159 1160 4 查詢中國的每個省的總城市數量和總人口數 1161 -- 能用where解決 不要用having解決. 1162 select 1163 district, 1164 count(*), 1165 sum(population) 1166 from 1167 city 1168 where 1169 countrycode = 'chn' 1170 group by 1171 district 1172 order by 1173 sum(population) desc; 1174 1175 1176 select 1177 countrycode, 1178 district, 1179 count(*), 1180 sum(population) 1181 from 1182 city 1183 group by 1184 countrycode, 1185 district 1186 having 1187 countrycode = 'chn' 1188 order by 1189 sum(population) desc; 1190 1191 5 Sweden國家說的是什麼語言? 1192 select 1193 co.name, 1194 cl.language, 1195 cl.isofficial 1196 from 1197 countrylanguage cl 1198 join 1199 country co 1200 on 1201 cl.countrycode = co.code 1202 where 1203 co.name = 'sweden'; 1204 1205 6 哪些國家沒有列出任何使用語言? 1206 select 1207 co.name, 1208 cl.language 1209 from 1210 countrylanguage cl 1211 right join 1212 country co 1213 on 1214 cl.countrycode = co.code 1215 where 1216 cl.language is null; 1217 1218 select 1219 co.name, 1220 count(cl.language) ct 1221 from 1222 countrylanguage cl 1223 right join 1224 country co 1225 on 1226 cl.countrycode = co.code 1227 group by 1228 co.name 1229 having 1230 ct = 0; 1231 1232 1233 7 列出在城市表中80%人口居住在城市的國家 1234 select 1235 co.name, 1236 sum(ci.population) / co.population rate 1237 from 1238 country co 1239 join 1240 city ci 1241 on 1242 co.code = ci.countrycode 1243 group by 1244 co.population, 1245 co.name 1246 having 1247 rate > 0.8; 1248 1249 1250 1251 1252 -- 子查詢 : 解決一次查詢不能解決的問題. 1253 select 1254 name, 1255 surfacearea, 1256 continent 1257 from 1258 country 1259 where surfacearea > 1260 (select 1261 avg(surfacearea) 1262 from 1263 country) 1264 1265 -- 子查詢用在比較運算中時, 必須返回一行一列. 下面的SQL是錯誤的 1266 select 1267 name, 1268 surfacearea, 1269 continent 1270 from 1271 country 1272 where surfacearea > 1273 (select 1274 avg(surfacearea) 1275 from 1276 country 1277 group by continent) 1278 1279 -- 找出哪個城市的人口是最多的. 1280 select 1281 countrycode, 1282 name, 1283 population 1284 from 1285 city 1286 where 1287 population = (select max(population) from city); 1288 1289 -- 找出平均壽命最高的和最低的國家. 1290 select 1291 continent, 1292 name, 1293 lifeExpectancy 1294 from 1295 country 1296 where 1297 lifeExpectancy in ( (select max(lifeExpectancy) from country), 1298 (select min(lifeExpectancy) from country)) 1299 1300 -- 檢視哪些國家的人口是大於本大洲平均人口. 1301 select 1302 co1.name, 1303 co1.continent, 1304 co1.population, 1305 co2.avgPop 1306 from 1307 country co1 1308 join 1309 (select 1310 continent, 1311 avg(population) avgPop 1312 from 1313 country 1314 group by 1315 continent) co2 1316 on 1317 co1.continent = co2.continent 1318 where 1319 co1.population > co2.avgPop 1320 order by 1321 continent; 1322 1323 -- 建立資料庫 1324 create database if not exists school charset gbk; 1325 1326 -- 修改資料庫, 只能修改預設字符集 1327 alter database school charset utf8; 1328 1329 -- 丟棄資料庫 1330 drop database if exists school; 1331 1332 -- 切換資料庫 1333 use school; 1334 1335 1336 資料型別 1337 int 4位元組整數 1338 bigint 8位元組整數 1339 char(長度) 定長字串, 長度最大255, 在實際插入資料時, 如果長度不夠, 會自動補齊. 1340 varchar(長度) 變長字串, 長度最大65535位元組, 在實際插入資料時, 如果長度不夠, 實際多少就佔多少空間. 1341 longtext 超長文字 1342 double 8位元組浮點數 1343 decimal 多位元組定點數 1344 date 日期 1345 time 時間 1346 datetime 日期時間 1347 timestamp 時間戳 1348 1349 -- 建立表, 必須至少要有一個列 1350 -- 主鍵 : 資料必須是非空且唯一. 1351 create table if not exists teacher( 1352 id int auto_increment, -- 將來這個列對應的資料可以自動生成. 必須作成主鍵 1353 name varchar(20), -- varchar資料型別必須要有長度. 1354 age int, 1355 salary double, 1356 gender enum('男', '女') default '男', 1357 primary key(id) -- 表級主鍵 1358 ) engine innodb charset utf8; -- 1359 1360 create table if not exists classes( 1361 id int auto_increment, 1362 name varchar(20) not null, -- not null 就是非空 1363 room char(3), 1364 begindate date, 1365 master int, --班主任是一個整數, 將來是某個老師的id 1366 primary key(id) 1367 ); 1368 1369 -- 建立學生表, id, name, age, gender, phone, class_id 1370 create table if not exists student ( 1371 id int auto_increment, 1372 name varchar(20), 1373 age int, 1374 gender enum('男', '女') default '男', 1375 phone varchar(15), 1376 class_id int, 1377 primary key(id) 1378 ); 1379 1380 insert into teacher( 1381 name, 1382 age, 1383 salary, 1384 gender 1385 ) values ( 1386 '佟剛', 1387 40, 1388 2000, 1389 '男' 1390 ); 1391 1392 insert into teacher( 1393 id, 1394 name, 1395 age, 1396 salary, 1397 gender 1398 ) values ( 1399 null, 1400 '芳芳', 1401 20, 1402 50000, 1403 '女' 1404 ); 1405 1406 1407 -- 基於子查詢建表, 把虛表變成實表 1408 create table country2 1409 as select * from world.country; -- 複製表, 只是機械的把虛表變實, 不能複製約束(主鍵) 1410 1411 -- 複製表結構建表, 沒有資料 1412 create table country3 1413 like world.country; 1414 1415 1416 +----------+-----------------+------+-----+---------+----------------+ 1417 | Field | Type | Null | Key | Default | Extra | 1418 +----------+-----------------+------+-----+---------+----------------+ 1419 | id | int(11) | NO | PRI | NULL | auto_increment | 1420 | name | varchar(20) | YES | | NULL | | 1421 | age | int(11) | YES | | NULL | | 1422 | gender | enum('男','女') | YES | | 男 | | 1423 | phone | varchar(15) | YES | | NULL | | 1424 | class_id | int(11) | YES | | NULL | | 1425 +----------+-----------------+------+-----+---------+----------------+ 1426 1427 insert into student( 1428 name, 1429 age, 1430 phone, 1431 class_id, 1432 address 1433 ) values( 1434 '小明', 1435 20, 1436 '2342342', 1437 1, 1438 '北京昌平' 1439 ); 1440 1441 -- 修改表 1442 alter table 表名 1443 -- 支援若干子名 1444 1445 -- 新增新列 1446 add column 新列名 資料型別(長度) 其他選項. 1447 1448 alter table student 1449 add column address varchar(200) not null; -- 新列追加在所有列的最後. 1450 1451 alter table student 1452 add column email varchar(50) after age; -- 在指定列後面新增新列 1453 1454 alter table student 1455 add column cardNo char(18) first; -- 在最前面新增新列 1456 1457 -- 修改列, 資料型別, 長度, 其他選項 1458 modify 列名 新資料型別(新長度) 新其他選項 1459 1460 alter table student 1461 modify name varchar(10) not null; 1462 1463 -- 重新命名列 1464 change 列名 新列名 新資料型別(新長度) 新其他選項; 1465 1466 alter table student 1467 change phone mobile char(11) unique; -- unique就是唯一. 1468 1469 -- 丟棄列 1470 drop column 列名; -- 會導致刪除的列所對應的所有資料全部丟失, 無法找回 1471 1472 alter table student 1473 drop column cardNo; 1474 1475 -- 重新命名錶 1476 rename to 新表名 1477 1478 alter table student 1479 rename to students; 1480 1481 alter table teacher 1482 rename to teachers; 1483 1484 -- 修改約束 1485 以上都是alter table 的子句, 用於修改表 1486 --------------------------------------------------------------- 1487 1488 -- 丟棄表 操作很危險, 如果沒有資料備份, 就永遠找不回來. 1489 drop table 表名; 1490 1491 -- 丟棄表時可以批量丟棄 1492 drop table country2, country3; 1493 1494 -- 清空表 DDL, 表中資料不能恢復. 效率高 1495 truncate table 表名; 1496 1497 delete 是DML, 是可以後悔的. 效率低. 1498 1499 1500 insert into teachers( 1501 name, 1502 age, 1503 salary, 1504 gender 1505 ) values ( 1506 '紅康', 1507 30, 1508 3000, 1509 '男' 1510 ); 1511 1512 insert into teachers( 1513 name, 1514 age, 1515 salary, 1516 gender 1517 ) value ( 1518 '小柴', 1519 20, 1520 5000, 1521 '女' 1522 ); 1523 1524 insert into teachers( 1525 name, 1526 age, 1527 salary, 1528 gender 1529 ) values ( 1530 '賀飛', 1531 35, 1532 4000, 1533 '男' 1534 ), ( 1535 '老韓', 1536 40, 1537 3000, 1538 '男' 1539 ), ( 1540 '安妮', 1541 32, 1542 6000, 1543 '女' 1544 ); 1545 1546 -- 不建議這樣的寫法. 因為它強烈依賴表的結構,如果表的結構發生變化, 下面的語句就容易失敗! 1547 insert into teachers values( 1548 null, 1549 '小邱', 1550 40, 1551 7000, 1552 '男' 1553 ); 1554 1555 +-----------+-------------+------+-----+---------+----------------+ 1556 | Field | Type | Null | Key | Default | Extra | 1557 +-----------+-------------+------+-----+---------+----------------+ 1558 | id | int(11) | NO | PRI | NULL | auto_increment | 1559 | name | varchar(20) | NO | | NULL | | 1560 | room | char(3) | YES | | NULL | | 1561 | begindate | date | YES | | NULL | | 1562 | master | int(11) | YES | | NULL | | 1563 +-----------+-------------+------+-----+---------+----------------+ 1564 1565 insert into classes ( 1566 name, 1567 room, 1568 begindate, 1569 master 1570 ) values ( 1571 'Java0725', 1572 '305', 1573 now(), -- 值的部分可以使用函式呼叫 1574 2 1575 ); 1576 1577 -- 實現表的完全克隆!!! 1578 create table if not exists country2 like world.country; 1579 1580 -- 基於子查詢插入資料, 好處就是一次性插入多條記錄. 1581 insert into country2 1582 select * from world.country; 1583 1584 1585 -- 事務 : 一組DML, 在執行時, 要麼全部失敗, 要麼全部成功, 使得資料從一種狀態轉換為另一種狀態. 資料沒有丟失!! 1586 1587 A Atomic 原子性 所有操作不可分割. 1588 C Consistence 一致性 資料在事務前和事務後資料是一致的. 1589 I ISOLATION 獨立性 不同事務之間具有隔離性 1590 D Duration 永續性 事務一旦提交, 永久生效. 1591 1592 DCL : 資料控制語言 : commit, rollback, grant, revoke... 1593 1594 顯式啟動事務 : 1595 set autocommit = false; 1596 set @@autocommit = off; 1597 1598 多條DML語句; 1599 1600 commit; 事務提交, 成功 1601 rollback; 事務回滾, 失敗 1602 ddl語句執行 : 事務提交 1603 會話正常結束 提交 1604 異常結束 : 回滾 1605 1606 1607 還原設定 1608 set autocommit = true; 1609 set @@autocommit = on; 1610 1611 1612 1613