您的位置:首页 > 数据库

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

2020-08-21 15:18 816 查看

一个人做饭简单食谱

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.

注释表中的斜体列名称

userId
bookId
是外键,这意味着它们是其他表中的主键,在这里用于引用这些表。

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
列时,它也很有用,因为您可以将它们重命名为
userId
commentId
等。

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 JOIN
INNER 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.

我喜欢将

WHERE
JOIN
COUNT
GROUP_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/

一个人做饭简单食谱

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐