10個SQL技巧之一:一切都是表

banq發表於2019-01-03

這是最瑣碎的技巧,甚至不是真正的技巧,但它是徹底理解SQL的基礎:一切都是一張表!當您看到如下的SQL語句時:

SELECT * FROM person


一張表person處於From後面,但你是否意識到整個宣告也是一張表?例如,你可以寫:

SELECT *
FROM (
  SELECT *
  FROM person
) t

現在,您已經建立了所謂的“派生表” - 即子句中的巢狀SELECT FROM語句。

這很平常,且相當優雅。您還可以在某些資料庫(例如PostgreSQL,SQL Server)中使用VALUES()構造器建立特殊的記憶體表:

SELECT *
FROM (
  VALUES(1),(2),(3)
) t(a)


這簡單地產生:

a
—
1
2
3


如果不支援該子句,則可以恢復為派生表,例如在Oracle中:

SELECT *
FROM (
  SELECT 1 AS a FROM DUAL UNION ALL
  SELECT 2 AS a FROM DUAL UNION ALL
  SELECT 3 AS a FROM DUAL
) t

現在您已經看到了這些VALUES()並且派生表實際上是相同的,從概念上講,讓我們回顧一下INSERT這兩種風格的語句:

-- SQL Server, PostgreSQL, some others:
INSERT INTO my_table(a)
VALUES(1),(2),(3);
  
-- Oracle, many others:
INSERT INTO my_table(a)
SELECT 1 AS a FROM DUAL UNION ALL
SELECT 2 AS a FROM DUAL UNION ALL
SELECT 3 AS a FROM DUAL


在SQL中,一切都是表。當您將行插入表中時,您實際上並未插入單個行。你真的插入整個表。大多數人恰好在大多數時間碰巧插入單行表,因此沒有意識到INSERT真正做到了什麼。

一切都是一張表。在PostgreSQL中,甚至函式都是表:

SELECT *
FROM substring('abcde', 2, 3)


輸出:

substring
———
bcd

如果您使用Java進行程式設計,則可以使用Java 8 Stream API的類比來更進一步。請考慮以下等效概念:

TABLE          : Stream<Tuple<..>>
SELECT         : map() 
DISTINCT       : distinct()
JOIN           : flatMap()
WHERE / HAVING : filter()
GROUP BY       : collect()
ORDER BY       : sorted()
UNION ALL      : concat()


使用Java 8,“一切都是流”(至少你開始使用Streams)。無論您如何變換流,例如使用map()或filter(),結果型別始終是Stream。

 

相關文章