SQL 32 (金风玉露一相逢,胜却人间无数)

employees表的所有员工的last_namefirst_name拼接起来作为Name,中间以一个空格区分
(注:
采用sqlite编译时,字符串拼接为 || 符号,concat函数不被支持;
采用mysql时,支持concat函数)
CREATE TABLE employees
( emp_no int(11) NOT NULL,
birth_date date NOT NULL,
first_name varchar(14) NOT NULL,
last_name varchar(16) NOT NULL,
gender char(1) NOT NULL,
hire_date date NOT NULL,
PRIMARY KEY (emp_no));
思路:
属于将两列内容利用各“编译器”特定的语句,来实现列之间的合并。
解答:
(1)sqlite Version

SELECT last_name || ' ' || first_name AS Name
FROM employees

*warning: *引号中间记得敲一记空格
(2)MySQL Version

SELECT CONCAT(last_name,' ',first_name) AS Name
FROM employees

SQL 33 (万物皆由人的意志而创造)

创建一个actor表,包含如下列信息

列表 类型 是否为NULL 含义
actor_id smallint(5) not null 主键id
first_name varchar(45) not null 名字
last_name varchar(45) not null 姓氏
last_update date not null 日期
思路:根据SQL编译的版本来选择具体的语句
解答:sqlite Version

CREATE TABLE IF NOT EXISTS actor(
    actor_id smallint(5) not null ,
    first_name varchar(45) not null,
    last_name varchar(45) not null,
    last_update date not null default(datetime('now','localtime')),
    primary key(actor_id)
)

warning:不过实际操作时,用MySQL将题解中的几个不同的方式尝试了一下,单纯的create table actor,以及不涉及默认时间的设定这一版代码无法跑通,原因目前还不了解。

SQL 34 批量插入数据(一支穿云箭)

题目描述
题目已经先执行了如下语句:

drop table if exists actor;
CREATE TABLE actor (
   actor_id  smallint(5)  NOT NULL PRIMARY KEY,
   first_name  varchar(45) NOT NULL,
   last_name  varchar(45) NOT NULL,
   last_update  DATETIME NOT NULL)

请你对于表actor批量插入如下数据(不能有2条insert语句哦!)

actor_id    first_name    last_name    last_update
1            PENELOPE    GUINESS     2006-02-15 12:34:33
2            NICK        WAHLBERG    2006-02-15 12:34:33

思路:对于选择数据进行插入。需要注意的是,插入数据涉及很多列信息时,需要注意插入数据与现存表之间的顺序问题。
(1)默认插入顺序与已知表顺序已知(或者说已知表顺序,也已知待插入数据顺序情况下):

INSERT INTO actor
VALUES (1, 'PENELOPE', 'GUINESS', '2006-02-15 12:34:33'),
       (2, 'NICK', 'WAHLBERG', '2006-02-15 12:34:33');

(2)已知表顺序和待插入顺序不一致(或者需要批量插入大规模数据,无法保证数据顺序均一致):

INSERT INTO actor(actor_id,
                 first_name,
                 last_name,
                 last_update)
VALUES(1,'PENELOPE','GUINESS','2006-02-15 12:34:33'),
      (2,'NICK','WAHLBERG','2006-02-15 12:34:33')

warning:此类语法下,actor_id 默认对应于输入数据中的“第一号位置”代表的内容,以此类推。

SQL 35 批量插入无重复数据(穿云箭+)

题目描述
题目已经先执行了如下语句:

drop table if exists actor;
CREATE TABLE actor (
   actor_id  smallint(5)  NOT NULL PRIMARY KEY,
   first_name  varchar(45) NOT NULL,
   last_name  varchar(45) NOT NULL,
   last_update  DATETIME NOT NULL);
insert into actor values ('3', 'WD', 'GUINESS', '2006-02-15 12:34:33');

对于表actor插入如下数据,如果数据已经存在,请忽略(不支持使用replace操作)

actor_id    first_name    last_name    last_update
'3'        'ED'           'CHASE'     '2006-02-15 12:34:33'

思路:插入无重复数据,利用语法。(注意,sqlite和MySQL语法使用上存在不同,不要混淆)
解答:
(1)sqlite Version

INSERT OR IGNORE INTO actor
VALUES(3,'ED','CHASE','2006-02-15 12:34:33')

(2)MySQL Version

INSERT IGNORE INTO actor
VALUES(3,'ED','CHASE','2006-02-15 12:34:33')

结合《SQL 必知必会15》 插入数据

(1)INSERT 能做什么?
A、插入完整的一行;
B、插入行的一部分;
C、插入某些查询的结果;
*warning:使用INSERT语句可能需要客户端/服务器DBMS中的特定安全权限。在试图使用INSERT前,应该保证自己有足够的安全权限。
A、插入完整行
需指定:(1)待插入表名 (2)插入到新行中的值

INSERT INTO Customs
VALUES('aa',
        'bb',
        'cc')

存储在CUSTOMS表中的每一列数据需要在VALUES子句中给出。(每一列需要提供一个值,如果为空则用NULL;各列数据需要依表列次序进行填充)
*warning:此语句高度依赖表列次序。不能经受变动,语句不安全。
Update Version

INSERT INTO Customs(V1,
                    V2,
                    V3)
VALUES('aa',
        'bb',
        'cc')

此新版本与第一版工作能力完全相同,但在“指定插入表名”后括号之中给出了“每一列的具体名称”。插入行数据时,VALUES只需要将待插入列数据对应输入即可。例:V1对应aa……
因为提供了列名,VALUES必须以列名指定顺序输入数据,但是这就不一定需要按照各列在表中实际顺序进行输入——也就是表结构发生改变,输入语句仍能正常运行。
B、插入行的一部分
引用A中的第二版本,我们可以在表名后括号内指定“列”。所以——借助此语句,我们可以指给一行中“部分列”提供数值。
warning:*在表定义允许的情况下**,可以在INSERT操作中省略某些列。只是“可省略列”需要满足以下要求:
(1)该列定义允许为NULL
(2)表于定义中给出“默认值”(即如不输入数值,则取默认A)
C、插入某些查询的结果(插入多行)

INSERT INTO Customs(V1,
                    V2,
                    V3)
SELECT V1,
       V2,
       V3
FROM Customs_old

*warning:注意两张表的“主键值”不要重复,否则后续INSERT会失败。但如果“SELECT”的表本身为“空”,那么将不会有行被插入,并不会产生错误。
SELECT 选择的列名并不重要!因为选择的第一列(无论名称一致否)对应“INSERT INTO”的第一列……(本质上是一个位置的对应关系)
(2)将A表内容复制到B表(新创建的表)
使用SELECT INTO 语句(DB2不支持)

Difference:
INSERT SELECT SELECT INTO
将A表内容插入至已存在的B表 将A表内容导出到新表B

SELECT *
INTO B
FROM A

此语句就是创建了新表“B”,并且将“A”表中的内容整个复制到了“B”中。(这里*作为通配符,代表将A全部内容复制到B,而如果只想选择部分列,则指定“列名”即可)
Version MySQL

CREATE TABLE B AS
SELECT * FROM A

*warning:使用SELECT INTO 语句的注意事项:
(1)SELECT语句的基本选项和语句此处都可使用。(含WHERE/GROUP BY)
(2)可利用联结从多个表中插入数据
(3)但只能插入到一个表中