SQL 查询表

了解如何使用 SQL SELECT、FROM、LIMIT、ORDER BY 和 AS 来查询和排序表。

使用 Metabase 学习 SQL

免费下载 Metabase,或注册 Metabase Cloud 免费试用

本章内容

  • 使用 SELECT 指定要获取的列
  • * 选择所有列
  • 使用 FROM 指定要查询的表或子查询
  • 在开发查询时,如果不对表进行聚合,请使用 LIMIT 限制行数(以免数据库崩溃)
  • 使用 -- 添加注释;注释不会影响结果,但会帮助他人理解您的代码
  • 每个查询以 ; 结尾
  • 使用 AS 更改列名
  • 使用 ORDER BY 对结果进行排序,ASC 为升序,DESC 为降序
  • 使用逗号分隔的列表选择特定列
  • 了解 SQL 大小写约定以及何时区分大小写
  • 使用 MOD 函数从表中抽取数据样本

SQL:获取表中的所有行

如果您想获取整个表及其所有行,就像这个 products 表一样

| id  | ean           | title                     | category  | vendor                       | price | rating | created_at                  |
| --- | ------------- | ------------------------- | --------- | ---------------------------- | ----- | ------ | --------------------------- |
| 1   | 1018947080336 | Rustic Paper Wallet       | Gizmo     | Swaniawski, Casper and Hilll | 29.46 | 4.6    | July 19, 2017, 7:44 PM      |
| 2   | 7663515285824 | Small Marble Shoes        | Doohickey | Balistreri-Ankunding         | 70.08 | 0      | April 11, 2019, 8:49 AM     |
| 3   | 4966277046676 | Synergistic Granite Chair | Doohickey | Murray, Watsica and Wunsch   | 35.39 | 4      | September 8, 2018, 10:03 PM |

您可以像这样从表中 SELECTFROM

SELECT
  *
FROM
  products;
  • SELECT 是 SQL 中的一个保留字,用于指定要返回的列。保留字是 SQL 中的关键字,对于处理查询的数据库引擎具有特殊含义。
  • * 是通配符运算符,它告诉数据库返回表中的所有列。通常,您应该只在结果中包含您想要的确切列。请勿在没有限制结果的情况下对非常大的表尝试此操作,除非您想让其他人的体验更糟糕。
  • FROM 是 SQL 中的一个保留字,它告诉数据库从哪个表(或多个表)查找列。表名必须精确(但大小写不敏感)。
  • 请注意查询末尾的 ;。Metabase 对于是否包含分号非常宽容,但其他编辑器/数据库可能并非如此。它们会查找分号以判断查询是否完成。

数据库引擎在处理查询时所经历的操作顺序与人们阅读代码时的操作顺序不同。通常,您无需考虑这一点,因为开发人员已经投入了大量时间来优化这些查询引擎。

SQL:为代码添加注释

您可以使用(并且应该)-- 为查询添加注释。以下是同一个查询,附带了说明性注释:

-- Our first query
SELECT
  * -- The star means to get all columns
FROM
  products; -- The table to query

数据库的查询处理器知道忽略 -- 之后同一行上的任何内容。事实上,即使您在查询中放入一艘完整的帆船,结果也不会改变。

SELECT
  *
FROM
-- An entire sailboat
  products;

SQL:仅从表中获取部分

您可以像这样 LIMIT 结果:

SELECT
  *
FROM
  products
LIMIT -- SQL reserved word
  3; -- Only get the first 3 rows

这将返回所有列 (*),但只返回 3 行。在开发查询时,尽可能限制行数以加快加载时间。幸运的是,Metabase 会自动将结果限制为前 2,000 行,这样人们就不会搞垮他们的数据库。但这仍然是一个好习惯。

LIMIT 只影响返回的行数。如果您正在聚合数据,例如计数行和分组行(我们稍后会介绍),数据库仍会计数并分组所有行,但只会返回由 LIMIT 设置的结果行数。

SQL:仅获取部分

要返回特定列,例如只返回 titlecategory

| title                     | category  |
| ------------------------- | --------- |
| Rustic Paper Wallet       | Gizmo     |
| Small Marble Shoes        | Doohickey |
| Synergistic Granite Chair | Doohickey |

按照您希望列在结果中显示的顺序 SELECT 各列。用逗号分隔列(但不要在列表末尾添加逗号),例如:

SELECT
  title, -- Names of each column must be exact
  category -- No comma at the end of list
FROM
  products;

事实上,许多人曾因缺少逗号而犯错,所以有些人会像这样格式化他们的 SQL,只是为了让逗号更容易看到(更重要的是,在需要时更容易注释掉列)。

SELECT
  title
  ,category -- Comma precedes each column except the first column
  ,vendor -- No comma at the end of list
FROM
  products;

SQL:对结果进行排序

您可以使用 ORDER BY 对结果行进行排序。例如,按价格从低到高对产品进行排序:

SELECT
  title,
  price
FROM
  products
ORDER BY     -- Sorts results
  price ASC; -- By the price column in ascending order

返回结果:

| Title                    | Price |
| ------------------------ | ----- |
| Mediocre Paper Car       | 15.69 |
| Rustic Paper Car         | 19.87 |
| Heavy-Duty Copper Gloves | 20.41 |
| Enormous Marble Shoes    | 21.42 |

ASC 关键字有时是可选的(取决于数据库引擎),但在 ORDER BY 子句中包含 ASC 可以使代码更易读,并且始终有效。

要以降序(从高到低)排序,请添加 DESC 关键字:

SELECT
  title,
  price
FROM
  products
ORDER BY
  price DESC; -- Sorts in descending order

要按多列排序,例如,首先按 category(按字母顺序)排序,然后按每个类别中的 price(从高到低)排序:

SELECT
  title,
  category,
  price
FROM
  products
ORDER BY
  category ASC, -- Sorts categories alphabetically (note the comma)
  price DESC; -- Then sorts prices highest to lowest within each category

您有时可能会看到人们按数字排序,如下所示:

SELECT
  title,
  category,
  price
FROM
  products
ORDER BY
  2 ASC, -- Sorts categories alphabetically (note the comma)
  3 DESC; -- Then sorts prices highest to lowest within each category

这里的数字对应于 SELECT 语句中列的序号位置。对于某些数据库,按位置排序是唯一可以按别名列排序的方式。但如果可能,最好包含列名或别名,这样人们在阅读代码时就不必在 SELECTORDER BY 部分之间来回切换。

SQL:更改列名

假设您的表中有像 titlecategory 这样的列名,但您希望每个列标题都以“Product”开头,如下所示:

| Product title             | Product category |
| ------------------------- | ---------------- |
| Rustic Paper Wallet       | Gizmo            |
| Small Marble Shoes        | Doohickey        |
| Synergistic Granite Chair | Doohickey        |

要更改列名(在结果中,而不是表本身),请使用 AS 为列创建别名,如下所示:

SELECT
  title AS "Product title", -- Note the double quotes, single quotes won't work
  category AS "Product category"
FROM
  products;

SQL 别名是查询中值的临时名称。别名对底层数据库没有任何影响;别名只存在于查询本身。您通常使用别名来:

  • 提高可读性。
  • 命名列表达式(例如,CONCAT(first_name, ' ', last_name) AS "Full name")。
  • 命名公共表表达式(请参阅 CTEs)。
  • 自连接表。

SQL 大小写通常不重要,别名除外

将 SQL 保留字全部大写是一种早于语法高亮显示的约定,但对于保留字或列名来说,字母大小写并不重要。这个查询也有效:

SeLeCt
  *
FrOM
  PROdUCTS;

但是,您懂的:不要这样做。编写易于人们(包括六个月后的您自己)阅读的查询。因此,无论是否全大写(SELECTselect),请保持一致。

然而,大小写确实适用于别名,因此请确保别名字母大小写完全匹配(对于别名,"Example""example" 不同)。

SQL:获取行样本

这仅在您的表具有随机分布的 ID 行时才有效。您可以使用 MOD 函数(模的缩写)根据 ID 对数据进行采样:

SELECT
  id,
  title,
  category
FROM
  products
WHERE
  -- For this to work, the table's ids must be sequential integers
  MOD(id, 10) = 3;

返回结果:

| id  | title                         | category   |
|-----|-------------------------------|------------|
| 3   | Synergistic Granite Chair     | Doohickey  |
| 13  | Synergistic Steel Chair       | Gizmo      |
| 23  | Fantastic Aluminum Bottle     | Widget     |

还有更多行,每第十行都有一个以 3 结尾的 ID。其工作原理是:例如,如果 ID 为 23,MOD(23, 10) 将返回 3,因为 23 除以 10 余 3,所以第 23 行将包含在结果中。这只是将结果除以 10,所以如果表有很多行,您会希望增加除数的数量级:100、1000 等。

这个技巧更多是为了激发您对 SQL 潜力的兴趣。我们稍后将深入探讨 SQL 函数(如 MOD)。

© . All rights reserved.