SQL笔记(二) - LC1484 / LC1667 / 字符串操作

Question

Activities

1
2
3
4
5
6
7
8
+-------------+---------+
| 列名 | 类型 |
+-------------+---------+
| sell_date | date |
| product | varchar |
+-------------+---------+
此表没有主键,它可能包含重复项。
此表的每一行都包含产品名称和在市场上销售的日期。

编写一个 SQL 查询来查找每个日期、销售的不同产品的数量及其名称。
每个日期的销售产品名称应按词典序排列。
返回按 sell_date 排序的结果表。

Solution

显然需要作一个对日期的 GROUP BY,数量的统计可以直接用 COUNT 函数完成,但我意识到对商品名称的拼接需要的聚合函数我完全不掌握,遂查看题解:

1
2
3
4
5
6
7
SELECT sell_date, COUNT(DISTINCT product) AS num_sold, GROUP_CONCAT(
DISTINCT product
ORDER BY product
SEPARATOR ','
) AS products
FROM Activities
GROUP BY sell_date

Question 2

表: Users

1
2
3
4
5
6
7
8
+----------------+---------+
| Column Name | Type |
+----------------+---------+
| user_id | int |
| name | varchar |
+----------------+---------+
user_id 是该表的主键。
该表包含用户的 ID 和名字。名字仅由小写和大写字符组成。
编写一个 SQL 查询来修复名字,使得只有第一个字符是大写的,其余都是小写的。
返回按 user_id 排序的结果表。

Solution 2

和上一题相同,想到了 UPPERLOWER 函数进行大小写变换,但完全想不出首字母大写的处理(子字符串函数)。发现自己对字符串函数的掌握还太欠缺:

1
2
3
SELECT user_id, CONCAT(UPPER(SUBSTRING(name, 1, 1)), LOWER(SUBSTRING(name, 2, LENGTH(name) - 1))) AS name
FROM Users
ORDER BY user_id

Keypoint

GROUP_CONCAT 函数

1
2
3
GROUP_CONCAT([DISTINCT] expression1
[ORDER BY expression2]
[SEPARATOR sep]);

GROUP_CONCAT 函数将组中的字符串连接成为单个字符串。SEPARATOR 指定在组中的值之间插入的文字值,若不指定,默认分隔符为,GROUP_CONCAT 函数忽略 NULL,如果找不到匹配的行,或者所有参数都为 NULL,则返回 NULL

CONCAT 函数

1
CONCAT(input_string1, input_string2 [, input_stringN]);

CONCAT 函数可将两个或多个字符串连接成一个字符串。如果传递非字符串值,CONCAT 函数将在连接之前将这些值隐式转换为字符串;NULL 会转换为空字符串。

SUBSTRING 函数

1
SUBSTRING(input_string, start, length);

SUBSTRING 从输入字符串中的位置开始提取具有指定长度的子字符串。如果 start + length > input_string 的长度,子字符串将包含剩余所有字符。

与大多数编程语言不同,参数 start 是从 1 开始的字符位置并非从 0 开始的下标;第三个参数是长度而非子串结束位置

UPPERLOWER 函数

1
2
UPPER(input_string);
LOWER(input_string);

UPPER / UCASE 函数将输入字符串转换为大写,LOWER / LCASE 函数将输入字符串转换为小写。

LEFTRIGHT 函数

1
2
LEFT(input_string, number_of_characters);
RIGHT(input_string, number_of_characters);

LEFT 函数从提供的字符串的左侧提取给定数量的字符,RIGHT 函数从提供的字符串的右侧提取给定数量的字符。