一个人做饭简单食谱_通过这5条简单食谱学习SQL

2023-05-16

一个人做饭简单食谱

SQL (Structured Query Language) is a powerful and expressive language for dealing with data from relational databases. But it can seem daunting to the uninitiated.

SQL(结构化查询语言)是一种功能强大的表达性语言,用于处理关系数据库中的数据。 但是对于初学者来说,这似乎令人生畏。

The "recipes" I'm going to share with you today are some basic examples from a simple database. But the patterns you'll learn here can help you write precise queries. These will have you feeling like the data equivalent of a MasterChef in no time.

我今天要与您分享的“食谱”是来自简单数据库的一些基本示例。 但是您将在此处学习的模式可以帮助您编写精确的查询。 这些将使您立即感觉就像MasterChef的数据一样。

A note about syntax: Most of the queries below are written in the style used for PostgreSQL from the psql command line. Different SQL engines can use slightly different commands.

有关语法的注释:以下大多数查询都是通过psql命令行以PostgreSQL所使用的样式编写的。 不同SQL引擎可以使用略有不同的命令。

Most of the queries below should work in most engines without tweaking, although some engines or GUI tools might require the omission of quotation marks around table and column names.

尽管某些引擎或GUI工具可能要求省略表名和列名的引号,但下面的大多数查询都应在大多数引擎中运行,而无需进行调整。

菜式1:返回在特定日期范围内创建的所有用户 (Dish 1: Return all the users created within a particular date range)

配料 (Ingredients)

  • SELECT

    选择
  • FROM

  • WHERE

    哪里
  • AND

方法 (Method)

SELECT *
FROM "Users"
WHERE "created_at" > "2020-01-01"
AND "created_at" < "2020-02-01";

This simple dish is a versatile staple. Here we are returning users that meet two particular conditions by chaining the WHERE conditions with an AND statement. We can extend this further with more AND statements.

这道简单的菜是多用途的主食。 在这里,我们通过将WHERE条件与AND语句链接在一起来返回满足两个特定条件的用户。 我们可以使用更多的AND语句进一步扩展它。

While the example here is for a specific date range, most queries require some sort of condition to filter the data usefully.

虽然此处的示例是针对特定日期范围的,但大多数查询都需要某种条件才能有效过滤数据。

菜式2:查找书籍的所有评论,包括发表评论的用户 (Dish 2: Find all comments for a book, including the user that made the comment)

(新)成分 ((New) Ingredients)

  • JOIN

    加入

方法 (Method)

SELECT "Comments"."comment", "Users"."username"
FROM "Comments"
JOIN "Users"
ON "Comments"."userId" = "Users"."id"
WHERE "Comments"."bookId" = 1;

This query assumes the following table structure:

该查询采用以下表结构:

One of the things that can start to confuse novices with SQL is the use of JOINs to find data from associated tables.

可能使新手与SQL混淆的一件事是使用JOIN从关联表中查找数据。

The ERD (Entity Relationship Diagram) above shows three tables, Users, Books, and Comments, and their associations.

上面的ERD(实体关系图)显示了三个表,用户,书籍和注释,以及它们的关联。

Each table has an id which is bold in the diagram to show that it is the primary key for the table. This primary key is always a unique value and is used to tell records in tables apart.

每个表都有一个id ,该id在图中是粗体的 ,以表明它是该表的主键。 该主键始终是唯一值,用于区分表中的记录。

The italic column names userId and bookId in the Comments table are foreign keys, which means they are the primary key in other tables and are used here to reference those tables.

注释表中的斜体列名称userIdbookId是外键,这意味着它们是其他表中的主键,在这里用于引用这些表。

The connectors in the ERD above also show the nature of the relationships between the 3 tables.

上面的ERD中的连接器还显示了3个表之间关系的性质。

The single point end on the connector means 'one' and the split end on the connector means 'many', so the User table has a 'one-to-many' relationship with the Comments table.

连接器上的单点端表示“一个”,连接器上的分叉端表示“许多”,因此“用户”表与“注释”表具有“一对多”关系。

A user can have many comments, for example, but a comment can only belong to a single user. Books and Comments have the same relationship in the diagram above.

例如,一个用户可以有很多评论,但是一个评论只能属于一个用户。 上图中的书籍和注释具有相同的关系。

The SQL query should make sense based on what we now know. We are returning only the named columns, i.e. the comment column from the Comments table and the username from the associated Users table (based on the referenced foreign key). In the example above we constrain the search to a single book, again based on the foreign key in the Comments table.

根据我们现在所知道的,SQL查询应该有意义。 我们仅返回命名列,即Comments表中的comment列和关联的Users表中的用户名(基于引用的外键)。 在上面的示例中,我们再次基于“注释”表中的外键将搜索限制为一本书。

菜式3:计算每个用户添加的评论数 (Dish 3: Count the number of comments added by each user)

(新)成分 ((New) Ingredients)

  • COUNT

    计数
  • AS

  • GROUP BY

    通过...分组

方法 (Method)

SELECT "Users"."username", COUNT("Comments"."id") AS "CommentCount"
FROM "Comments"
JOIN "Users"
ON "Comments"."userId" = "Users"."id"
GROUP BY "Users"."id";

This little query does a few interesting things. The easiest to understand is the AS statement. This allows us to arbitrarily, and temporarily, rename columns in the data that gets returned. Here we rename the derived column, but it's also useful when you have multiple id columns, since you can rename them things like userId or commentId and so on.

这个小查询做了一些有趣的事情。 最容易理解的是AS语句。 这使我们可以任意地,临时地重命名要返回的数据中的列。 在这里,我们重命名了派生列,但是当您有多个id列时,它也很有用,因为您可以将它们重命名为userIdcommentId等。

The COUNT statement is a SQL function that, as you'd expect, counts things. Here we count the number of comments associated with a user. How does it work? Well the GROUP BY is the important final ingredient.

如您所料, COUNT语句是一个SQL函数,它对事物进行计数。 在这里,我们计算与用户关联的评论数。 它是如何工作的? 好吧, GROUP BY是重要的最终成分。

Let's briefly imagine a slightly different query:

让我们简要地想象一下一个稍微不同的查询:

SELECT "Users"."username", "Comments"."comment"
FROM "Comments"
JOIN "Users"
ON "Comments"."userId" = "Users"."id";

Notice, no counting or grouping. We just want each comment and who made it.

注意,没有计数或分组。 我们只想要每个评论以及发表评论的人。

The output might look something like this:

输出可能看起来像这样:

|----------|-----------------------------|
| username | comment                     |
|----------|-----------------------------|
| jackson  | it's good, I liked it       |
| jackson  | this was ok, not the best   |
| quincy   | excellent read, recommended |
| quincy   | not worth reading           |
| quincy   | I haven't read this yet     |
------------------------------------------

Now imagine we wanted to count Jackson's and Quincy's comments - easy to see at a glance here, but harder with a larger dataset as you can imagine.

现在想象一下,我们想计算一下Jackson和Quincy的评论-在这里一目了然,但想像中的更大数据集却很难。

The GROUP BY statement essentially tells the query to treat all the jackson records as one group, and all the quincy records as another. The COUNT function then counts the records in that group and returns that value:

GROUP BY语句实质上是告诉查询将所有jackson记录视为一组,而将所有quincy记录视为另一组。 然后, COUNT函数计算该组中的记录并返回该值:

|----------|--------------|
| username | CommentCount |
|----------|--------------|
| jackson  | 2            |
| quincy   | 3            |
---------------------------

菜式4:查找未发表评论的用户 (Dish 4: Find users that have not made a comment)

(新)成分 ((New) Ingredients)

  • LEFT JOIN

    左联接
  • IS NULL

    一片空白

方法 (Method)

SELECT "Users"."username"
FROM "Users"
LEFT JOIN "Comments"
ON "Users"."id" = "Comments"."userId"
WHERE "Comments"."id" IS NULL;

The various joins can get very confusing, so I won't unpack them here. There is an excellent breakdown of them here: Visual Representations of SQL Joins, which also accounts for some of the syntax differences between various flavours or SQL.

各种连接可能会非常混乱,因此在这里我不会解压缩它们。 这里有一个很好的细分: SQL Joins的可视表示 ,它也解释了各种形式或SQL之间的某些语法差异。

Let's imagine an alternate version of this query quickly:

让我们快速想象一下该查询的替代版本:

SELECT "Users"."username", "Comments"."id" AS "commentId"
FROM "Users"
LEFT JOIN "Comments"
ON "Users"."id" = "Comments"."userId";

We still have the LEFT JOIN but we've added a column and removed the WHERE clause.

我们仍然有LEFT JOIN但是我们添加了一个列并删除了WHERE子句。

The return data might look something like this:

返回数据可能看起来像这样:

|----------|-----------|
| username | commentId |
|----------|-----------|
| jackson  | 1         |
| jackson  | 2         |
| quincy   | NULL      |
| abbey    | 3         |
------------------------

So Jackson is responsible for comments 1 and 2, Abbey for 3, and Quincy has not commented.

因此,杰克逊负责评论1和2,修道院负责3,而昆西没有评论。

The difference between a LEFT JOIN and an INNER JOIN (what we've been calling just a JOIN until now, which is valid) is that the inner join only shows records where there are values for both tables. A left join, on the other hand, returns everything from the first, or left, table (the FROM one) even if there is nothing in the right table. An inner join would therefore only show the records for Jackson and Abbey.

LEFT JOININNER JOIN (到目前为止,我们一直称其为JOIN ,这是有效的)之间的区别在于,内部INNER JOIN仅显示两个表都具有值的记录。 另一方面,即使右表中没有任何内容,左FROM也会FROM一个表或左表( FROM之一)返回所有内容。 因此,内部联接只会显示Jackson和Abbey的记录。

Now that we can visualize what the LEFT JOIN returns, it's easier to reason about what the WHERE...IS NULL part does. We return only those users where the commentId is a null value, and we don't actually need the null value column included in the output, hence its original omission.

现在我们可以看到LEFT JOIN返回的内容,现在更容易WHERE...IS NULL部分的作用。 我们仅返回commentId为空值的那些用户,并且实际上不需要输出中包括空值列,因此可以忽略其原始内容。

菜式5:在单个字段中列出每个用户添加的所有评论,并用管道分隔 (Dish 5: List all comments added by each user in a single field, pipe separated)

(新)成分 ((New) Ingredients)

  • GROUP_CONCAT or STRING_AGG

    GROUP_CONCAT或STRING_AGG

方法(MySQL) (Method (MySQL))

SELECT "Users"."username", GROUP_CONCAT("Comments"."comment" SEPARATOR " | ") AS "comments"
FROM "Users"
JOIN "Comments"
ON "Users"."id" = "Comments"."userId"
GROUP BY "Users"."id";

方法(PostgreSQL) (Method (Postgresql))

SELECT "Users"."username", STRING_AGG("Comments"."comment", " | ") AS "comments"
FROM "Users"
JOIN "Comments"
ON "Users"."id" = "Comments"."userId"
GROUP BY "Users"."id";

This final recipe shows a difference in syntax for a similar function in two of the most popular SQL engines.

最后的配方显示了两个最受欢迎SQL引擎中相似函数的语法差异。

Here is a sample output we might expect:

这是我们可能期望的示例输出:

|----------|---------------------------------------------------|
| username | comments                                          |
|----------|---------------------------------------------------|
| jackson  | it's good, I liked it | this was ok, not the best |
| quincy   | excellent read, recommended | not worth reading   |
----------------------------------------------------------------

We can see here that the comments have been grouped and concatenated / aggregated, that is joined together in a single record field.

我们在这里可以看到,注释已被分组和连接/聚合,并在单个记录字段中连接在一起。

胃口 (Bon Appetit)

Now that you have some SQL recipes to fall back on, get creative and serve up your own data dishes!

现在您有了一些可以依靠SQL食谱,可以发挥创意并提供自己的数据服务!

I like to think of WHERE, JOIN, COUNT, GROUP_CONCAT as the Salt, Fat, Acid, Heat of database cooking. Once you know what you're doing with these core elements, you are well on your way to mastery.

我喜欢将WHEREJOINCOUNTGROUP_CONCAT视为数据库烹饪的盐,脂肪,酸,热 。 一旦了解了这些核心元素的功能,就可以很好地掌握。

If this has been a useful collection, or you have other favourite recipes to share, drop me a comment or follow on Twitter: @JacksonBates.

如果这是一个有用的收藏,或者您有其他喜欢的食谱可以分享,请给我评论或在Twitter上关注@JacksonBates 。

翻译自: https://www.freecodecamp.org/news/sql-recipes/

一个人做饭简单食谱

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

一个人做饭简单食谱_通过这5条简单食谱学习SQL 的相关文章

  • 导出 Azure SQL 数据库时出现错误 SQL71501

    导出 Azure SQL 数据库时出现奇怪的错误 导出一直工作正常 直到最近发生一些架构更改 但现在出现错误 SQL71501 该数据库是V12 兼容性级别130 尽管master数据库仍兼容级别 120 该问题似乎是由一个新的表值函数引起
  • Visual Studio 2008 (C#) 与 SQL Compact Edition 数据库错误:26

    与网络相关或特定于实例的 建立时发生错误 连接到 SQL Server 服务器 未找到或无法访问 验证实例名称是否为 正确并且 SQL Server 是 配置为允许远程 连接 提供商 SQL 网络 接口 错误 26 错误定位 指定服务器 实
  • 不使用窗口函数实现 SQL 查询

    我读过 可以通过创造性地使用连接等来实现在 SQL 窗口函数中可以执行的任何操作 但我不知道如何实现 我在这个项目中使用 SQLite 它目前没有窗口函数 我有一个有四列的表 CREATE TABLE foo id INTEGER PRIM
  • SQL查询多行变成单行

    有什么方法可以将通常返回具有相同值的多行的 SQL 查询更改为单行吗 例如 如果我现有的查询返回以下内容 ColA ColB 1 AA 1 BB 1 CC 2 AA 3 AA 我可以将查询更改为仅返回 3 行 并将 1 的第二个和第三个结果
  • 如何授予用户访问 SQL Server 中的 sys.master_files 的权限?

    我需要授予数据库用户读取权限sys master files桌子 我怎样才能做到这一点 目前用户拥有以下权限 Calling SELECT on sys master files返回空结果 我还使用以下命令测试了相同的查询sa用户按预期工作
  • Oracle中如何转义单引号? [复制]

    这个问题在这里已经有答案了 我有一列包含某些存储为文本字符串的表达式 其中包括单个引号 例如 错过的交易 包括引号 发生这种情况时如何使用 where 子句 select from table where reason missed tra
  • 哪种 SQL 模式能够更快地避免插入重复行?

    我知道有两种不重复插入的方法 第一个是使用WHERE NOT EXISTS clause INSERT INTO table name col1 col2 col3 SELECT s s s WHERE NOT EXISTS SELECT
  • 仅使用 SQL 中的 MAX 函数更新重复行

    我有一张这样的桌子 假设为了举例 NAME是一个唯一的标识符 NAME AGE VALUE Jack Under 65 3 Jack 66 74 5 John 66 74 7 John Over 75 9 Gill 25 35 11 Som
  • 导致聚集索引扫描的日期参数

    我有以下查询 DECLARE StartDate DATE 2017 09 22 DECLARE EndDate DATE 2017 09 23 SELECT a col1 a col2 b col1 b col2 b col3 a col
  • 关系数据库和图数据库的比较

    有人可以向我解释一下 MySQL 等关系数据库与 Neo4j 等图形数据库相比的优缺点吗 在 SQL 中 您有多个表 它们之间有不同的 id 链接 然后你必须加入来连接表 从新手的角度来看 为什么要将数据库设计为需要联接 而不是像图形数据库
  • 为什么 Orchard 在执行内容项查询时如此慢?

    假设我想查询所有 Orchard 用户 ID 并且还想包括那些已被删除 也称为软删除 的用户 该数据库包含大约 1000 个用户 Option A 大约需要 2 分钟 Orchard ContentManagement IContentMa
  • 动态SQL生成列名?

    我有一个查询 我正在尝试将行值转换为列名称 目前我正在使用SUM Case As ColumnName 声明 像这样 SELECT SKU1 SUM Case When Sku2 157 Then Quantity Else 0 End A
  • 从Oracle表中删除重复行

    我正在 Oracle 中测试某些内容并使用一些示例数据填充表 但在此过程中我不小心加载了重复记录 因此现在我无法使用某些列创建主键 如何删除所有重复行并只保留其中一行 Use the rowid伪列 DELETE FROM your tab
  • SQL Not Empty 代替 Not NULL

    我正在使用 postgreSQL 我有一个专栏 NOT NULL 但是 当我想插入带有空字符串的行时 如下所示 它不会给我错误并接受 我如何检查插入值应该是not empty 既不为空也不为空 PS 我的专栏定义为 ads characte
  • 数据库“key/ID”设计思想、代理键、主键等

    因此 我最近看到多次提到代理键 但我不太确定它是什么以及它与主键有何不同 我总是假设 ID 是表中的主键 如下所示 Users ID Guid FirstName Text LastName Text SSN Int 然而 维基百科将代理键
  • PHP 中的 SQL 语句与 phpmyadmin 中的 SQL 语句的行为不同

    I have form store sql INSERT INTO myodyssey myaccount id email username password VALUES NULL email unixmiah formtest woo
  • sqlite 插入表中 select * from

    我需要在 Android 应用程序中将数据从一个表移动到另一个表 我想使用以下sql insert into MYTABLE2 select id STATUS risposta DATETIME now data ins from MYT
  • 如何将 LEFT JOIN 限制为 SQL Server 中的第一个结果?

    我有一些 SQL 几乎可以做我想做的事情 我正在使用三个表 Users UserPhoneNumbers 和 UserPhoneNumberTypes 我正在尝试获取用户列表及其电话号码以供导出 数据库本身很旧并且存在一些完整性问题 我的问
  • 在单个查询中设置和选择?

    我想知道是否可以在单个查询中设置和选择 像这样的事情 SET LOCAL search path TO 1 SET LOCAL ROLE user SELECT from posts 你可以这样做 with some set as sele
  • 当我耗尽 bigint 生成的密钥时会发生什么?怎么处理呢?

    我自己无法想象一个好的答案 所以我想在这里问 在我心里 我总是想知道 如果AUTO INCREMENT PRIMARY ID我的专栏MySQL表用完了吗 举例来说 我有一个有两列的表 一个ID auto increment primary

随机推荐