SQL快速入門 ( MySQL快速入門, MySQL參考, MySQL快速回顧 )

SQL

先說點廢話,好久沒發文了,整理了下本身當時入門 SQL 的筆記,不管用於入門,回顧,參考查詢,應該都是有必定價值的,能夠按照目錄各取所需。SQL數據庫有不少,MySQL是一種,本文基本都是SQL通用標準,有些標準很不統一的地方就用MySQL的寫法了。但願本文幫你快速瞭解SQL的基本操做和概念。
文章格式上有些問題,能夠點擊這裏得到更加的閱讀體驗mysql

目錄

檢索

  • 檢索某表中單個列:
    SELECT 列名
    FROM 表名;
  • 檢索某表中多個列:
    SELECT 列名,列名,列名
    FROM 表名;
  • 檢索某表中全部列:(儘可能不用)
    SELECT *
    FROM 表名;
  • 只檢索某表中某列裏不重複的項:
    SELECT DISTINCT 列名 (若是有兩列或以上,須要這些列組合起來是不重複的)
    FROM 表名;
  • 檢索指定行數:
    SELECT 列名
    FROM 表名
    LIMIT 5 OFFSET n; (mySQL中,選第n行後的五行。 OFFSET n 可不填寫默認爲0,其它 SQL 數據庫中有不一樣寫法)

過濾檢索結果

  • 尋找指定行:(舉例)
SELECT prod_name, prod_price  
    FROM Products  
    WHERE prod_price = 3.49;(和字符串比較加單引號,數值不用)
查找列名爲prod_name和列名爲prod_price的兩列,檢索其中prod_price = 3.49; 的全部行。  
= 能夠替換爲其它操做符,以下表

| 操做符 | 描述 |
| --- | --- |
| = | 等於 |
| <> | 不等於 |
| > | 大於 |
| < | 小於 |
| >= | 大於等於 |
| <= | 小於等於 |
| BETWEEN | 在某個範圍內 |
| LIKE | 搜索某種模式 |
  • 組合WHERE子句:
SELECT prod_id, prod_price, prod_name
    FROM Products
    WHERE vend_id = 'DLL01' AND prod_price <= 4;
AND 鏈接同時須要知足的兩個條件,OR即知足一個條件便可,NOT 找到與後邊條件不匹配的行。  
且not,and和or能夠組合使用,用小括號聲明邏輯循序。  
`WHERE vend_id IN ( 'DLL01', 'BRS01' ) `  
IN 起到做用相似於or,速度更快,邏輯更清晰。
  • 通配符搜索:
SELECT prod_id, prod_name
    FROM Products
    WHERE prod_name LIKE '%bean bag%';
%表示任意字符出現任意次數。也能夠出如今中間位置。  
_ 表示一個字符。  
[charlist] 表示包含在裏面的任意字符,[^charlist]不包含在裏面的任意字符。
少使用通配符,搜索速度較慢。

數據彙總處理

  • 算術計算:
SELECT prod_id,
            quantity,
            item_price,
            quantity * item_price AS expanded_price
    FROM OrderItems
    WHERE order_num = 20008;
`expanded_price`成爲計算出來的新列。
  • 字符串拼接:
    不一樣數據庫有差別,MySQL中:
SELECT concat(vend_name , vend_country)
            AS vend_title
    FROM Vendors
    ORDER BY vend_name;
concat_ws( ':' , vend_name , vend_country) 形式第一個參數爲分隔符。  
其餘數據庫用+或者||拼接字符串。
  • 日期時間處理不一樣數據庫差別較大。
  • 內置方法:
    • 求平均值:
      SELECT AVG(prod_price) AS avg_price
      FROM Products;
      表Products中prod_price的平均值。返回給 avg_price。
      能夠配合WHERE語句計算指定行的平均值。
    • 求最大值:MAX(prod_price)
    • 求最小值:MIN(prod_price)
    • 求和:SUM(prod_price)
    • 近似的小數點後幾位:ROUND(column_name,decimals)
    • 當前日期: Now()
    • 求行數:
      SELECT COUNT(*) AS num_cust
      FROM Customers;
      求表Customers有幾行。返回給num_cust。
      *能夠換成指定列如:cust_email。計算所得行數不包括該列值爲null的行。
      DISTINCT 列名,求不重複的列。
  • 組合:
SELECT COUNT(*) AS num_items,
           MIN(prod_price) AS price_min,
           MAX(prod_price) AS price_max,
           AVG(prod_price) AS price_avg
    FROM Products;

分組

  • 建立分組:
SELECT vend_id
    FROM Products
    GROUP BY vend_id;
根據 vend_id列中內容對 vend_id分組,  
第一行換成 `SELECT vend_id, COUNT(*) AS num_prods` 即對每個組計算行數。  
注意:多行NULL會分爲一組,GROUP BY子句必須出如今WHERE子句以後,ORDER BY子句以前。  
能夠對一個以上的列進行 GROUP BY
  • 過濾分組:
    HAVING:相似於WHERE。惟一的差異是,WHERE過濾行,而HAVING過濾分組。
SELECT vend_id, COUNT(*) AS num_prods
    FROM Products
    WHERE prod_price >= 4
    GROUP BY vend_id
    HAVING num_prods >= 2;
過濾出有(兩個價格大與4的產品)的供應商

給檢索結果排序

SELECT Company, OrderNumber 
FROM Orders 
ORDER BY Company DESC, OrderNumber ASC

能夠 ORDER BY 列名1,列名2; 先按列名1內容排序,排序結果相同的按列名2內容排序。
列名後接 DESC 按該列內容倒序排列,ASC 正序(默認)。
ORDER BY 命令放在查詢、分組等語句的最後。git

表操做

  • 建立表:
CREATE  TABLE  newProducts
    (
        prod_id         CHAR(10)           NOT NULL,
        vend_id         CHAR(10)           NOT NULL,
        prod_name       CHAR(254)          NOT NULL,
        prod_price      DECIMAL(8,2)       NOT NULL,
        prod_desc       VARCHAR(1000)      NULL
    );
NOT NULL 非空約束,不容許列中有NULL值下面介紹其餘約束。  
列的設置能夠加上默認值,如NOT NULL後邊接 DEFAULT  CURRENT_DATE() ,默認值爲當前日期。(每一個數據庫獲取當前日期語句不一樣。)
後面接 PRIMARY KEY 即設置改列爲主鍵。
後面接  AUTO_INCREMENT 即設置爲自增,只有int型能夠設置。
  • 約束:
    每一個列能夠有一種或幾種約束。
    • NOT NULL 非空約束.
    • UNIQUE 惟一約束,可惟一標識數據庫表中的每條記錄。
    • PRIMARY KEY 主鍵約束,惟一標識數據庫表中的每條記錄,惟一且非空。
    • FOREIGN KEY 外鍵約束,一個表中的 FOREIGN KEY 指向另外一個表中的 PRIMARY KEY。
    • CHECK 檢查約束,用於限制列中的值的範圍。
    • DEFAULT 默認約束,用於向列中插入默認值
      每一個表能夠有多個 UNIQUE 約束,可是每一個表只能有一個 PRIMARY KEY 約束。
      每種約束能夠建立表時設置好,也能夠後期增刪.
  • 索引:
    在不讀取整個表的狀況下,索引使數據庫應用程序能夠更快地查找數據。
CREATE INDEX 索引名
    ON Person (列名[,列名])
  • 複製表或表中部分列:
CREATE  TABLE CustCopy AS
    SELECT * FROM Customers;
建立Customers表的複製,CustCopy。
  • 修改表:
ALTER TABLE Vendors
    ADD vend_phone CHAR(20);
    ALTER TABLE Vendors
    DROP COLUMN vend_phone;
各數據庫有不兼容現象,複雜表操做列可能要新建表刪除舊錶。  
ALTER 還能夠用來添加刪除約束,刪除索引等。
  • 刪除表:
    DROP TABLE CustCopy;
  • 重命名錶:
    RENAME Table oldTable TO newTable;

插入數據

  • 插入整行或部分行:
INSERT INTO Customers(cust_id,
                            cust_name,
                            cust_address,
                            cust_city,
                            cust_state,
                            cust_zip,
                            cust_country,
                            cust_contact,
                            cust_email)
    VALUES('1000000007',
            'Toy Land',
            '123 Any Street',
            'New York',
            'NY',
            '11111',
            'USA',
            NULL,
            NULL);
插入整行時,可省略 Customers 括號內的內容,即按照列的順序,分別插入數據(不推薦)。省略 Customers 括號內的內容時,無內容的列必須用NULL佔位。  
插入部分行時,把要插入的列填入 Customers 括號內,與VALUES內容一一對應,沒有提到的列默認NULL或其餘默認值。
  • 插入查詢到的值:
INSERT INTO Customers(cust_id,
                            cust_contact,
                            cust_email,
                            cust_name,
                            cust_address,
                            cust_city,
                            cust_state,
                            cust_zip,
                            cust_country)
    SELECT cust_id,
            cust_contact,
            cust_email,
            cust_name,
            cust_address,
            cust_city,
            cust_city,
            cust_state,
            cust_zip,
            cust_country
    FROM CustNew;
把從CustNew表中查到的內容插入 Customers表中。一次插入多行的方式。

更新和刪除數據:

  • 更新數據:
UPDATE Customers
    SET cust_email = 'kim@thetoystore.com'
    WHERE cust_id = '1000000005';
步驟爲,要更新的表,要更新的列,要更新的行。一個SET能夠跟多個列用逗號隔開。  
刪除某個值,即設置他爲NULL。
  • 刪除數據:
DELETE FROM Customers
    WHERE cust_id = '1000000008';
刪除表中指定整行,刪除部分列用UPDATE  
在UPDATE或DELETE語句使用WHERE子句前,應該先用SELECT進行測試,保證它過濾的是正確的記錄,以防編寫的WHERE子句不正確。若是不寫WHERE會更新或刪除全部行內容。

子查詢-迭代查詢

  • 一種形式:
SELECT cust_name, cust_contact
    FROM Customers
    WHERE cust_id IN (SELECT cust_id
        FROM Orders
        WHERE order_num IN (SELECT order_num
            FROM OrderItems
            WHERE prod_id = 'RGAN01'));
先從第二個括號選擇符合條件的order_num,成爲第二個括號內容,再向上找到第一個括號,查到符合條件的cust_id返回給第一個括號,最後根據第一個括號內容執行主查詢語句。性能問題不要嵌套太多層。  
也就是對Customers表的查詢要用到Orders表查詢後返回的內容,對Orders表的查詢要用到OrderItems表查詢後返回的內容。
  • 另外一種形式:
SELECT cust_name,
        cust_state,
        (SELECT COUNT(*)
            FROM Orders
            WHERE Orders.cust_id = Customers.cust_id) AS orders
    FROM Customers
根據Customers 表中的cust_id,去Orders表中取得計算後的數據。
  • 同一個表迭代查詢:
SELECT cust_id, cust_name, cust_contact
    FROM Customers
    WHERE cust_name = (SELECT cust_name
                    FROM Customers
                    WHERE cust_contact = 'Jim Jones');

聯結-關聯多個表

  • 兩個表:
    • 內聯結
    SELECT vend_name, prod_name, prod_price
          FROM Vendors, Products
          WHERE Vendors.vend_id = Products.vend_id;
    根據兩個表共同的列vend_id把Vendors, Products關聯起來。
      與
    SELECT vend_name, prod_name, prod_price
          FROM Vendors INNER JOIN Products
          ON Vendors.vend_id = Products.vend_id;
    結果相同。都是內聯結,前一種是後一種的簡寫。  
      INNER 可省略。
    • 外聯結:
    SELECT Customers.cust_id, Orders.order_num
          FROM Customers LEFT OUTER JOIN Orders
          ON Orders.cust_id = Customers.cust_id;
    LEFT OUTER JOIN 把Customers表中沒有被匹配到的 cust_id 也聯結進去(會顯示在結果裏)。  
      RIGHT OUTER JOIN 是把Orders表中沒有被匹配到的 cust_id 也聯結進去(會顯示在結果裏)。  
      FULL OUTER JOIN 會把兩張表中沒有匹配到的列也顯示出來(mysql 不支持,可經過 UNION 實現)
      OUTER 可省略。
  • 多個表:
SELECT cust_name, cust_contact
    FROM Customers, Orders, OrderItems
    WHERE Customers.cust_id = Orders.cust_id
    AND OrderItems.order_num = Orders.order_num
    AND prod_id = 'RGAN01';
做用同子查詢中a。一樣不要關聯太多,有性能問題。其中表名可使用別名,如:
SELECT cust_name, cust_contact
    FROM Customers AS C, Orders AS O, OrderItems AS OI
    WHERE C.cust_id = O.cust_id
    AND OI.order_num = O.order_num
    AND prod_id = 'RGAN01';

組合查詢

SELECT cust_name, cust_contact, cust_email 
FROM Customers 
WHERE cust_state IN ('IL','IN','MI') 
UNION ALL
SELECT cust_name, cust_contact, cust_email 
FROM Customers 
WHERE cust_name = 'Fun4All';

UNION ALL 連接兩句查詢語句,統一返回結果,包含重複結果。
去掉ALL之後,去掉重複結果。
此處(從同一個表中查詢)能夠用WHERE , OR代替。
經常使用做從不一樣表中查詢時,只要列數相同就能夠拼接到一塊兒,列名按照第一句中查詢的列名。github

視圖

對已存在的表,進行篩選,數據處理,聯結等操做後返回的數據,建立的虛擬表。視圖是爲了重用和簡化經常使用的查詢。對視圖的查詢同表。
視圖老是顯示最近的數據。每當用戶查詢視圖時,數據庫引擎經過使用 SQL 語句來重建數據。sql

  • 建立視圖:
CREATE  VIEW ProductCustomers AS                
    SELECT cust_name, cust_contact, prod_id
    FROM Customers, Orders, OrderItems
    WHERE Customers.cust_id = Orders.cust_id
    AND OrderItems.order_num = Orders.order_num;
對OrderItems, Orders和Customers三個表進行聯結,聯結後結果造成 ProductCustomers 視圖,能夠把它當一張表來查詢。
  • 刪除視圖:
    DROP VIEW ProductCustomers;數據庫

    其它

  • 存儲過程:爲之後的使用保存一條或多條SQL語句,用於簡化操做。每一個數據庫不一樣,見數據庫具體介紹。
  • 事務處理:事務處理模塊中的語句,或者所有執行,或者所有不執行。能夠設立保留點,執行失敗時回到保留點。
  • 建立數據庫: CREATE DATABASE database_name
  • 刪除數據庫:DROP DATABASE 數據庫名稱性能

相關文章
相關標籤/搜索