博客 / 詳情

返回

創建計算字段:讓數據“按需重組”

存儲在數據庫中的原始數據,往往不符合直接使用的格式(比如分散在多列的信息、需要計算的數值),這時候“計算字段”就能派上用場——它不是表中實際存在的列,而是運行時通過SQL語句動態創建的虛擬列。

  1. 核心用法:拼接與算術運算
    字段拼接:用Concat()函數將多列數據合併為一個字段,比如將供應商名稱和國家拼接成“名稱(國家)”格式:
    SELECT Concat(RTrim(vend_name), '(', RTrim(vend_country), ')') AS vend_title
    FROM vendors;
    其中RTrim()用於去除字段右側多餘空格,AS給計算字段起別名(別名是客户機引用該列的關鍵)。
    算術計算:直接對數值型字段進行加減乘除運算,比如計算訂單中每項物品的總金額(單價×數量):
    SELECT prod_id, quantity, item_price,
    quantity * item_price AS expanded_price
    FROM orderitems WHERE order_num = 20005;
  2. 關鍵技巧:別名的正確使用
    別名不僅能簡化計算字段的引用,還能解決列名含特殊字符、名稱不清晰的問題。命名時建議簡潔明瞭,比如用total_price代替quantity*item_price,讓SQL語句更易讀。

二、數據處理函數:給數據“做精加工”
函數是SQL處理數據的“工具箱”,能快速完成文本格式化、日期計算、數值轉換等操作。MySQL支持文本、日期時間、數值三類常用函數,重點掌握這些高頻用法:

  1. 文本處理函數:搞定字符串格式
    大小寫轉換:Upper()(轉大寫)、Lower()(轉小寫)
    截取與查找:Left()(取左側字符)、Locate()(查找子串位置)
    去空格:Trim()(去除首尾空格)、RTrim()(去除右側空格)
    語音匹配:Soundex()(按發音匹配字符串,比如匹配“Y.Lee”和“Y.Lie”):
    SELECT cust_name FROM customers
    WHERE Soundex(cust_contact) = Soundex('Y Lie');
  2. 日期時間函數:精準處理時間數據
    日期是SQL查詢中高頻過濾條件,核心函數用法如下:

獲取當前時間:Now()(日期+時間)、CurDate()(僅日期)
提取日期成分:Year()(年份)、Month()(月份)、Day()(天數)
日期比較:用Date()函數忽略時間部分,只對比日期:
SELECT cust_id FROM orders
WHERE Date(order_date) = '2005-09-01';

  1. 數值處理函數:簡化數學運算
    常用函數包括Abs()(絕對值)、Rand()(隨機數)、Sum()(求和)等,多用於數值型數據的統計與轉換。

三、彙總數據:用聚集函數快速統計
當需要對數據進行統計分析(比如求平均值、計數、找最值)時,不需要逐行檢索數據,直接用聚集函數就能快速得到結果。

  1. 5個核心聚集函數
    函數 功能
    AVG() 返回某列平均值(忽略NULL值)
    COUNT() 統計行數(COUNT(*)含NULL,COUNT(列名)不含NULL)
    MAX() 返回某列最大值
    MIN() 返回某列最小值
    SUM() 返回某列值之和
  2. 實用示例
    計算所有產品的平均價格:
    SELECT AVG(prod_price) AS avg_price FROM products;
    統計有電子郵件的客户數量:
    SELECT COUNT(cust_email) AS num_cust FROM customers;
    合計某訂單的總金額:
    SELECT SUM(quantity * item_price) AS total FROM orderitems WHERE order_num = 20005;
    四、分組數據:按條件分類統計
    彙總函數默認對整個表生效,而GROUP BY子句能將數據按指定列分組,讓聚集函數對每個組單獨計算,比如“統計每個供應商的產品數量”“每個客户的訂單數”。
  3. 基礎用法:GROUP BY + 聚集函數
    SELECT vend_id, COUNT(*) AS num_prods
    FROM products GROUP BY vend_id;
    該語句按vend_id分組,統計每個供應商的產品數量。
  4. 關鍵補充:HAVING過濾分組
    WHERE用於過濾行,HAVING用於過濾分組(只能跟在GROUP BY後)。比如篩選出產品數量≥2且單價≥10的供應商:

SELECT vend_id, COUNT(*) AS num_prods
FROM products WHERE prod_price >= 10
GROUP BY vend_id HAVING COUNT(*) >= 2;

  1. 注意事項
    GROUP BY後列出的列,必須是SELECT中的非聚集列(或表達式);
    分組後如需排序,需加ORDER BY(GROUP BY不保證分組順序)。
    五、子查詢:用“查詢嵌套”解決複雜問題
    子查詢(嵌套查詢)是將一個查詢結果作為另一個查詢的條件或字段,適合解決“多步驟”的數據檢索,比如“找出訂購了某產品的所有客户”。
  2. 核心場景:WHERE子句中的子查詢
    比如查找訂購了產品TNT2的客户名稱,需分3步:①找含TNT2的訂單號→②找這些訂單對應的客户ID→③找客户ID對應的客户信息,用子查詢可合併為一條語句:

SELECT cust_name FROM customers
WHERE cust_id IN (
SELECT cust_id FROM orders
WHERE order_num IN (

SELECT order_num FROM orderitems WHERE prod_id = 'TNT2'

)
);

  1. 進階用法:作為計算字段的子查詢
    比如統計每個客户的訂單總數,將子查詢作為計算字段:

SELECT cust_name,
(SELECT COUNT(*) FROM orders WHERE orders.cust_id = customers.cust_id) AS orders
FROM customers;
這種“相關子查詢”會對外部查詢的每一行執行一次內部查詢,需注意列名的完全限定(比如orders.cust_id),避免歧義。

六、聯結表:打破數據孤島(重點!)
關係數據庫中,數據被分散存儲在多個表中(比如客户表、訂單表、產品表),聯結(JOIN)是將這些表按關聯關係組合查詢的核心技術,也是SQL最強大的功能之一。

  1. 先搞懂:為什麼需要聯結?
    比如要查詢“客户名稱+訂單號+訂購產品”,這些信息分散在customers、orders、orderitems三個表中,只有通過聯結才能一次性檢索,避免數據重複存儲(比如客户信息不會在每個訂單中重複)。
  2. 基礎聯結:內部聯結(等值聯結)
    最常用的聯結方式,通過兩表中相同的列(比如vendors.vend_id和products.vend_id)匹配數據:

SELECT vend_name, prod_name, prod_price
FROM vendors, products
WHERE vendors.vend_id = products.vend_id;
或用標準SQL的INNER JOIN語法(更清晰,推薦使用):

SELECT vend_name, prod_name, prod_price
FROM vendors INNER JOIN products
ON vendors.vend_id = products.vend_id;

  1. 關鍵提醒:避免笛卡兒積
    如果聯結時忘記寫WHERE或ON條件,MySQL會返回兩表的“笛卡兒積”(行數=表1行數×表2行數),導致數據冗餘且無意義,一定要注意!
  2. 多表聯結示例
    查詢訂單20005的客户名稱、產品名和數量,需聯結3個表:

SELECT cust_name, prod_name, quantity
FROM customers, orders, orderitems
WHERE customers.cust_id = orders.cust_id
AND orderitems.order_num = orders.order_num
AND orderitems.order_num = 20005;
總結:SQL進階的核心邏輯
這6章內容層層遞進,從“處理單表數據”(計算字段、函數),到“統計單表數據”(彙總、分組),再到“跨表關聯數據”(子查詢、聯結),本質是逐步提升數據處理的“維度”和“靈活性”。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.