【group by】
對結果集進行分組,常與匯總函數一起使用。
SELECT column,SUM(column) FROM table GROUP BY column
HAVING 通常與 GROUP BY 子句同時使用。不使用 GROUP BY 時, HAVING 則與 WHERE 子句功能相似。
Company Amount
W3Schools 5500
IBM 4500
W3Schools 7100
按照 Company 字段進行分組,求出每個 Company 的 Amout 的合計在 10000 以上的數據:
SELECT Company,SUM(Amount) FROM Sales GROUP BY Company HAVING SUM(Amount)>10000
返回結果 :
Company SUM(Amount)
W3Schools 12600
===============================================================
WHERE語句在GROUP BY語句之前;SQL會在分組之前計算WHERE語句。
HAVING語句在GROUP BY語句之后;SQL會在分組之后計算HAVING語句。
===============================================================
SELECT Customer,SUM(OrderPrice) FROM Orders
WHERE Customer='Bush'OR Customer='Adams'GROUPBY Customer
HAVINGSUM(OrderPrice)>1500
===============================================================
訂單總金額少於 2000 的客戶。
SELECT Customer,SUM(OrderPrice) FROM Orders
GROUPBY Customer
HAVINGSUM(OrderPrice)<2000
===============================================================
本例返回 "Persons" 表中的行數:SELECT COUNT(*) FROM Persons
返回大於 20 歲的人數:SELECT COUNT(*) FROM Persons WHERE Age>20
SELECT COUNT(DISTINCT Customer) AS NumberOfCustomers FROM Orders
【http://www.w3school.com.cn/sql/】【根據已整理的資料,系統地學習】
SQL 指令
FROM Store_Information
WHERE Sales > 1000;
FROM Store_Information
WHERE Sales > 1000
OR (Sales < 500 AND Sales > 275);
FROM Store_Information
WHERE Store_Name IN ('Los Angeles', 'San Diego');
FROM Store_Information
WHERE Txn_Date BETWEEN 'Jan-06-1999' AND 'Jan-10-1999';
FROM "表格名"
WHERE "欄位名" LIKE {套式};
{套式} 經常包括野卡 (wildcard). 以下是幾個例子:
- 'A_Z': 所有以 'A' 起頭,另一個任何值的字原,且以 'Z' 為結尾的字串。 'ABZ' 和 'A2Z' 都符合這一個模式,而 'AKKZ' 並不符合 (因為在 A 和 Z 之間有兩個字原,而不是一個字原)。
- 'ABC%': 所有以 'ABC' 起頭的字串。舉例來說,'ABCD' 和 'ABCABC' 都符合這個套式。
- '%XYZ': 所有以 'XYZ' 結尾的字串。舉例來說,'WXYZ' 和 'ZZXYZ' 都符合這個套式。
- '%AN%': 所有含有 'AN' 這個套式的字串。舉例來說, 'LOS ANGELES' 和 'SAN FRANCISCO' 都符合這個套式。
FROM Store_Information
WHERE Store_Name LIKE '%AN%';
FROM "表格名"
[WHERE "條件"]
ORDER BY "欄位名" [ASC, DESC];
FROM Store_Information
ORDER BY Sales DESC;
在以上的例子中,我們用欄位名來指定排列順序的依據。除了欄位名外,我們也可以用欄位的順序 (依據 SQL 句中的順序)。在 SELECT 后的第一個欄位為 1,第二個欄位為 2,以此類推。在上面這個例子中,我們打以下這一句 SQL 可以達到完全一樣的效果:
FROM Store_Information
ORDER BY 2 DESC;
- AVG (平均)
- COUNT (計數)
- MAX (最大值)
- MIN (最小值)
- SUM (總合)
FROM "表格名";
FROM Store_Information
WHERE Store_Name IS NOT NULL;
FROM Store_Information;
FROM "表格名"
GROUP BY "欄位1";
FROM Store_Information
GROUP BY Store_Name;
FROM "表格名"
GROUP BY "欄位1"
HAVING (函數條件);
請讀者注意: GROUP BY 子句並不是一定需要的。
SELECT Store_Name, SUM(Sales)FROM Store_Information
GROUP BY Store_Name
HAVING SUM(sales) > 1500;
FROM "表格名" "表格別名";
FROM Store_Information A1
GROUP BY A1.Store_Name;
FROM Geography A1, Store_Information A2
WHERE A1.Store_Name = A2.Store_Name
GROUP BY A1.Region_Name;
在第一行中,我們告訴 SQL 去選出兩個欄位:第一個欄位是 Geography 表格中的 Region_Name 欄位 (我們取了一個別名叫做 REGION);第二個欄位是 Store_Information 表格中的 Sales 欄位 (別名為 SALES)。請注意在這里我們有用到表格別名:Geography 表格的別名是 A1,Store_Information 表格的別名是 A2。若我們沒有用表格別名的話, 第一行就會變成
很明顯地,這就復雜多了。在這里我們可以看到表格別名的功用:它能讓 SQL 句容易被了解,尤其是這個 SQL 句含蓋好幾個不同的表格時。
接下來我們看第三行,就是 WHERE 子句。 這是我們闡述連接條件的地方。在這里,我們要確認Geography 表格中 Store_Name 欄位的值與 Store_Information 表格中 Store_Name 欄位的值是相等的。這個 WHERE 子句是一個連接的靈魂人物,因為它的角色是確定兩個表格之間的連接是正確的。如果 WHERE 子句是錯誤的,我們就極可能得到一個笛卡兒連接 (Cartesian Join)。笛卡兒連接會造成我們得到所有兩個表格每兩行之間所有可能的組合。在這個例子中,笛卡兒連接會讓我們得到 4 x 4 = 16 行的結果。
我們需要知道每一間店的營業額。如果我們用一個普通的連接,我們將會漏失掉 'New York' 這個店,因為它並不存在於 Store_Information 這個表格。所以,在這個情況下,我們需要用外部連接來串聯這兩個表格:
FROM Georgraphy A1, Store_Information A2
WHERE A1.Store_Name = A2.Store_Name (+)
GROUP BY A1.Store_Name;
我們在這里是使用了 Oracle 的外部連接語法。
請注意: 當第二個表格沒有相對的資料時,SQL 會傳回 NULL 值。在這一個例子中,'New York' 並不存在於 Store_Information 表格,所以它的 "SALES" 欄位是 NULL。FROM "表格"
WHERE "欄位2" [比較運算素]
(SELECT "欄位1"
FROM "表格"
WHERE "條件");
我們要運用 subquery 來找出所有在西部的店的營業額。我們可以用下面的 SQL 來達到我們的目的:
WHERE Store_name IN
(SELECT store_name FROM Geography
WHERE region_name = 'West');
UNION
[SQL 語句 2];
UNION
SELECT Txn_Date FROM Internet_Sales;
結果:
Txn_Date |
Jan-05-1999 |
Jan-07-1999 |
Jan-08-1999 |
Jan-08-1999 |
Jan-07-1999 |
Jan-10-1999 |
Jan-11-1999 |
Jan-12-1999 |
INTERSECT
SELECT Txn_Date FROM Internet_Sales;
MINUS
SELECT Txn_Date FROM Internet_Sales;
有的時候,我們有需要將由不同欄位獲得的資料串連在一起。每一種資料庫都有提供方法來達到這個目的:
- MySQL: CONCAT( )
- Oracle: CONCAT( ), ||
- SQL Server: +
MySQL/Oracle:
WHERE Store_Name = 'Boston';
Oracle:
WHERE Store_Name = 'Boston';
結果:
- MySQL: SUBSTR( ), SUBSTRING( )
- Oracle: SUBSTR( )
- SQL Server: SUBSTRING( )
由 <str> 中,選出所有從第 <pos> 位置開始的字元。請注意,這個語法不適用於 SQL Server 上。
由 <str> 中的第 <pos> 位置開始,選出接下去的 <len> 個字元。
FROM Geography
WHERE Store_Name = 'Los Angeles';
結果:
例2
FROM Geography
WHERE Store_Name = 'San Diego';
結果:
SQL 中的 TRIM 函數是用來移除掉一個字串中的字頭或字尾。最常見的用途是移除字首或字尾的空白。這個函數在不同的資料庫中有不同的名稱:
- MySQL: TRIM( ), RTRIM( ), LTRIM( )
- Oracle: RTRIM( ), LTRIM( )
- SQL Server: RTRIM( ), LTRIM( )
各種 trim 函數的語法如下:
TRIM ( [ [位置] [要移除的字串] FROM ] 字串): [位置] 的可能值為 LEADING (起頭), TRAILING (結尾), or BOTH (起頭及結尾)。 這個函數將把 [要移除的字串] 從字串的起頭、結尾,或是起頭及結尾移除。如果我們沒有列出 [要移除的字串] 是什么的話,那空白就會被移除。
LTRIM(字串): 將所有字串起頭的空白移除。
RTRIM(字串): 將所有字串結尾的空白移除。
例1
結果:
例2
結果:
例3
結果:
表格處理
(First_Name char(50),
Last_Name char(50),
Address char(50),
City char(50),
Country char(25),
Birth_Date datetime);
AS SELECT First_Name, Last_Name, Country
FROM Customer;
我們就可以用以下的指令來建一個包括每個地區 (Region) 銷售額 (Sales) 的視觀表:
AS SELECT A1.Region_Name REGION, SUM(A2.Sales) SALES
FROM Geography A1, Store_Information A2
WHERE A1.Store_Name = A2.Store_Name
GROUP BY A1.Region_Name;
這就給我們有一個名為 V_REGION_SALES 的視觀表。這個視觀表包含不同地區的銷售哦。如果我們要從這個視觀表中獲取資料,我們就打入,
若我們要在 Last_Name 這個欄位上建一個索引,我們就打入以下的指令,
ON Customer (Last_Name);
若我們要在 Last_Name 這個欄位上建一個索引,我們就打入以下的指令,
ON Customer (City, Country);
[改變方式];
[改變方式] 的詳細寫法會依我們想要達到的目標而有所不同。再以上列出的改變中,[改變方式] 如下:
- 加一個欄位: ADD "欄位 1" "欄位 1 資料種類"
- 刪去一個欄位: DROP "欄位 1"
- 改變欄位名稱: CHANGE "原本欄位名" "新欄位名" "新欄位名資料種類"
- 改變欄位的資料種類: MODIFY "欄位 1" "新資料種類"
MySQL:
(SID integer,
Last_Name varchar(30),
First_Name varchar(30),
PRIMARY KEY (SID));
Oracle:
(SID integer PRIMARY KEY,
Last_Name varchar(30),
First_Name varchar(30));
SQL Server:
(SID integer PRIMARY KEY,
Last_Name varchar(30),
First_Name varchar(30));
以下則是以改變現有表格架構來設定主鍵的方式:
MySQL:
Oracle:
SQL Server:
請注意,在用 ALTER TABLE 語句來添加主鍵之前,我們需要確認被用來當做主鍵的欄位是設定為 『NOT NULL』 ;也就是說,那個欄位一定不能沒有資料。
MySQL:
(Order_ID integer,
Order_Date date,
Customer_SID integer,
Amount double,
PRIMARY KEY (Order_ID),
FOREIGN KEY (Customer_SID) REFERENCES CUSTOMER (SID));
Oracle:
(Order_ID integer PRIMARY KEY,
Order_Date date,
Customer_SID integer REFERENCES CUSTOMER (SID),
Amount double);
SQL Server:
(Order_ID integer PRIMARY KEY,
Order_Date datetime,
Customer_SID integer REFERENCES CUSTOMER (SID),
Amount double);
以下的例子則是藉着改變表格架構來指定外來鍵。這里假設 ORDERS 表格已經被建置,而外來鍵尚未被指定:
MySQL:
ADD FOREIGN KEY (Customer_SID) REFERENCES CUSTOMER (SID);
Oracle:
ADD (CONSTRAINT fk_orders1) FOREIGN KEY (Customer_SID) REFERENCES CUSTOMER (SID);
SQL Server:
ADD FOREIGN KEY (Customer_SID) REFERENCES CUSTOMER (SID);
VALUES ("值1", "值2", ...);
SELECT "欄位3", "欄位4", ...
FROM "表格2";
SELECT store_name, Sales, Txn_Date
FROM Sales_Information
WHERE Year (Txn_Date) = 1998;
SET Sales = 500
WHERE Store_Name = 'Los Angeles'
AND Txn_Date = 'Jan-08-1999';
在這個例子中,只有一筆資料符合 WHERE 子句中的條件。如果有多筆資料符合條件的話,每一筆符合條件的資料都會被修改的。
我們也可以同時修改好幾個欄位。這語法如下:
SET "欄位1" = [值1], "欄位2" = [值2]
WHERE "條件";
WHERE Store_Name = 'Los Angeles';
SQL 指令的語法。簡潔的 SQL 語法做為讀者參考之用。
Select
SELECT "欄位" FROM "表格名";
Distinct
SELECT DISTINCT "欄位"
FROM "表格名";
Where
SELECT "欄位"
FROM "表格名"
WHERE "條件";
And/Or
SELECT "欄位"
FROM "表格名"
WHERE "簡單條件"
{[AND|OR] "簡單條件"}+;
In
SELECT "欄位"
FROM "表格名"
WHERE "欄位" IN ('值1', '值2', ...);
Between
SELECT "欄位"
FROM "表格名"
WHERE "欄位" BETWEEN '值1' AND '值2';
Like
SELECT "欄位"
FROM "表格名"
WHERE "欄位" LIKE {模式};
Order By
SELECT "欄位"
FROM "表格名"
[WHERE "條件"]
ORDER BY "欄位" [ASC, DESC];
Count
SELECT COUNT("欄位")
FROM "表格名";
Group By
SELECT "欄位1", SUM("欄位2")
FROM "表格名"
GROUP BY "欄位1";
Having
SELECT "欄位1", SUM("欄位2")
FROM "表格名"
GROUP BY "欄位1"
HAVING (欄位);
Create Table
CREATE TABLE "表格名"
("欄位 1" "欄位 1 資料種類",
"欄位 2" "欄位 2 資料種類",
... );
Drop Table
DROP TABLE "表格名";
Truncate Table
TRUNCATE TABLE "表格名";
Insert Into
INSERT INTO "表格名" ("欄位1", "欄位2", ...)
VALUES ("值1", "值2", ...);
Update
UPDATE "表格名"
SET "欄位1" = [新值]
WHERE "條件";
Delete From
DELETE FROM "表格名"
WHERE "條件";