zoukankan      html  css  js  c++  java
  • 数据库SQL学习(一)

    创建和使用数据库

    在创建和使用数据库之前,先介绍几个命令

    ## 该SHOW语句查找服务器上当前存在的数据库:
    ## 该mysql数据库描述了用户访问权限。该test数据库通常可作为用户工作区尝试的事情了。
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sakila             |
    | sys                |
    | world              |
    +--------------------+
    6 rows in set (0.11 sec)
     
    ## use 命令表示使用指定的 mysql 数据库
    mysql> use mysql
    Database changed
    mysql>
    

    一,创建和选择数据库

    ## 1. 创建数据库
    mysql> create database menagerie;
    Query OK, 1 row affected (0.04 sec)
    
    ## 删除数据库
    mysql> drop database menagerie;
    
    ## 注意:如果您收到错误,例如ERROR 1044(42000):在尝试创建数据库时,用户'micah'@'localhost'拒绝访问数据库'menagerie',这意味着您的用户帐户没有必要的权限。
     
    ## 2. 选择数据库,创建数据库时并不会选择它使用; 你必须明确地说明使用当前数据库,请使用以下语句:
    mysql> use menagerie
    Database changed
     
    ## 3. 进入数据库同时,选择使用指定数据库
    C:UserszjyDesktop $>mysql -uroot -p menagerie
    Enter password: ******
     
    ## 4. 执行完3之后,你可以通过 select database(),确认是否已经使用制定数据库
    mysql> select database();
    +------------+
    | database() |
    +------------+
    | menagerie  |
    +------------+
    1 row in set (0.00 sec)
    

    二,创建表

    创建数据库之后,我们可以看看它里面有什么

    ## 该menagerie数据库是空的集合
    mysql> show tables;
    Empty set (0.02 sec)
    

    更难的部分是决定数据库的结构应该是什么:您需要哪些表以及每个表中应该包含哪些列。

    您想要一张包含每只宠物记录的表格。这可以称为pet表格,它应该包含每个动物名称的最低限度。因为名称本身不是很有趣,所以该表应包含其他信息。例如,如果您家中有多个人饲养宠物,您可能需要列出每只动物的主人。您可能还想记录一些基本的描述性信息,如物种和性别。

    年龄怎么样?这可能是有意义的,但存储在数据库中并不是一件好事。随着时间的推移,年龄会发生变化,这意味着您必须经常更新记录。相反,最好存储固定值,如出生日期。然后,无论何时需要年龄,您都可以将其计算为当前日期和出生日期之间的差异.MySQL提供了进行日期算术的功能,因此这并不困难。存储出生日期而不是年龄也有其他优点:

    • 您可以使用数据库执行任务,例如为即将到来的宠物生日生成提醒(如果您认为这种类型的查询有些愚蠢,请注意,您可能会在业务数据库的上下文中询问相同的问题,以确定您需要在当前一周或一个月内向其发送生日祝福的客户,计算机辅助个人触摸。)
    • 您可以计算与当前日期以外的日期相关的年龄。例如,如果您将死亡日期存储在数据库中,则可以轻松计算宠物死亡时的年龄。

    您可能会想到在pet表格中有用的其他类型的信息,但到目前为止确定的信息是足够的:名称,所有者,物种,性别,出生和死亡。

    可以使用创建表指定表的布局,对于名称来说,名称,所有者,种三列的值的长度是不尽相同的,我们使用可变长度的字符VARCHAR,的性别性别可以使用单个字符'm'状语从句:  'f',或者可能'male'和  'female'。最简单的是使用单个字符'm'和'f';对于birth和death 列使用date数据类型是一个相当明显的选择。

    mysql> create table pet (name varchar(20),owner varchar(20),
        -> species varchar(20), sex char(1), birth date, death date);
    Query OK, 0 rows affected (0.26 sec)
    

    让我们来看看创建表之后的数据库

    mysql> show tables;
    +---------------------+
    | Tables_in_menagerie |
    +---------------------+
    | pet                 |
    +---------------------+
    1 row in set (0.00 sec)
    

    你可能不太满意,我希望看到更详细的表结构,验证表是否按预期方式创建,使用以下描述语句:

    mysql> describe pet;
    +---------+-------------+------+-----+---------+-------+
    | Field   | Type        | Null | Key | Default | Extra |
    +---------+-------------+------+-----+---------+-------+
    | name    | varchar(20) | YES  |     | NULL    |       |
    | owner   | varchar(20) | YES  |     | NULL    |       |
    | species | varchar(20) | YES  |     | NULL    |       |
    | sex     | char(1)     | YES  |     | NULL    |       |
    | birth   | date        | YES  |     | NULL    |       |
    | death   | date        | YES  |     | NULL    |       |
    +---------+-------------+------+-----+---------+-------+
    6 rows in set (0.00 sec)
    

    如果你忘记了表中列的名称或它们具有的类型,使用可以该 描述 命令

    三,将数据加载到表中

    创建表后,可以你用该 LOAD DATA 状语从句:INSERT语句将数据填充到表中。
    假设您的宠物记录可以如下所示进行描述。(注意MySQL期望'YYYY-MM-DD'格式的日期;这可能与你习惯的不同。),

    pet.txt文件格式
    每一项之间用Tab键进行分隔,如果该字段为NULL,则用N表示。
    
    Fluffy  Harol   cat     f   1993-02-04      2019-10-06	N
    Kifu	Hadon   dag	    m	1998-03-04	    2019-10-06	N
    Piger	Wang    bird	f	2003-05-01	    2019-10-06	N
    Yao	    Meng	nake	m	2008-02-04	    2019-10-06	N
    Du	    Tian    pig	    f 	1999-02-04    	2019-10-06	N
    Zhang   Jinrui 	bird   	m  	1998-02-04    	2019-10-06	N
    
    
    • 1.创建表 create table pet();

    • 2.写一个用于导入的文本文件 每一项之间用Tab键进行分隔,如果该字段为NULL,则用N表示。

    • 3.导入数据 输入命令,进行导入。

    load data local infile “d:/pet.txt”
    into table pet;
    或
    load data local infile “d:/pet.txt”
    into table pet( , , , , , ,);
    

    1. LOAD DATA方式载入文件数据

    使用这种方式,你首先需要创建一个文件,如per.txt,将导入表格的数据写在一个该文件中,每行包含一个记录,其值由制表符分隔,并按照CREATE TABLE语句中列出的顺序给出。对于缺失值(例如未知性别或仍然生活的动物的死亡日期),你可以使用NULL 值。要在文本文件中表示  NULL 值,请使用  N(反斜杠,大写-N)。下面给出一个例子:

    Fluffy    Harold    cat    f    1993-02-04    N
    
    字幕:要将文件加载pet.txt到  pet表中,请使用以下语句:
    
    mysql> load data local infile "D:/pet.txt" into table pet;
    

    如果出现这个版本的数据库不支持该命令,这是因为安装的MySQL数据库时,系统自动设置本地INFILE的值为假,这么做的目的是为了防止别人恶意进行数据注入,攻击数据库,所以一般线上数据库都会关闭该load data local语句功能:

    mysql> load data local infile "D:/pet.txt" into table pet;
    ERROR 1148 (42000): The used command is not allowed with this MySQL version
    mysql>
    

    解决方法

    2. INSERT方式,插入数据记录

    mysql> insert into pet
        -> values ('Puffball','Diane','hamster','f','1999-03-30',NULL);
    Query OK, 1 row affected (0.00 sec)
    

    四,从表中检索信息

    SELECT 语句用于从表中提取信息。声明的一般形式是:
    
    SELECT what_to_select
    FROM which_table
    WHERE conditions_to_satisfy;
    
    • what_to_select 表示想要看到的内容(可以是列名或者* ,* 代表所有列);
    • which_table 表示要从哪一个表检索数据;
    • where条件是可选的。如果存在,则 conditions_to_satisfy 指定行必须满足的一个或多个条件才有资格进行检索。

    一、检索所有数据

    mysql> select * from pet;
    +----------+--------+---------+------+------------+------------+
    | name     | owner  | species | sex  | birth      | death      |
    +----------+--------+---------+------+------------+------------+
    | Fluffy   | Harold | cat     | f    | 1993-02-04 | 0000-00-00 |
    | Claws    | Gwen   | cat     | m    | 1994-03-17 | 0000-00-00 |
    | Buffy    | Harold | dog     | f    | 1989-05-13 | 0000-00-00 |
    | Fang     | Benny  | dog     | m    | 1990-08-27 | 0000-00-00 |
    | Bowser   | Diane  | dog     | m    | 1979-08-31 | 1995-07-29 |
    | Chirpy   | Gwen   | bird    | f    | 1998-09-11 | 0000-00-00 |
    | Whistler | Gwen   | bird    | NULL | 1997-12-09 | 0000-00-00 |
    | Slim     | Benny  | snake   | m    | 1996-04-29 | 0000-00-00 |
    | Puffball | Diane  | hamster | f    | 1999-03-30 | NULL       |
    +----------+--------+---------+------+------------+------------+
    9 rows in set (0.00 sec)
     
    ## 修改指定的一条记录的一个字段值
    mysql> update pet
        -> set birth = '1989-08-31'
        -> where name = 'Bowser';
    Query OK, 1 row affected (0.07 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
     
    ## 查询是否更改成功,可以看到,生日更改了
    mysql> select * from pet where name = 'Bowser';
    +--------+-------+---------+------+------------+------------+
    | name   | owner | species | sex  | birth      | death      |
    +--------+-------+---------+------+------------+------------+
    | Bowser | Diane | dog     | m    | 1989-08-31 | 1995-07-29 |
    +--------+-------+---------+------+------------+------------+
    1 row in set (0.00 sec)
    

    二、检索特定行数据

    mysql>  SELECT * 
            FROM pet 
            WHERE name = 'Bowser';
    +--------+-------+---------+------+------------+------------+
    | name   | owner | species | sex  | birth      | death      |
    +--------+-------+---------+------+------------+------------+
    | Bowser | Diane | dog     | m    | 1989-08-31 | 1995-07-29 |
    +--------+-------+---------+------+------------+------------+
    

    字符串比较通常不区分大小写,因此您可以将名称指定为'bowser', 'BOWSER'等等。查询结果是一样的。

    ## 你可以在任何列上指定条件,而不仅仅是 name。例如,如果您想知道1998年或之后出生的动物:
    mysql> select * from pet where birth>='1998-1-1';
    +----------+-------+---------+------+------------+-------+
    | name     | owner | species | sex  | birth      | death |
    +----------+-------+---------+------+------------+-------+
    | Chirpy   | Gwen  | bird    | f    | 1998-09-11 | NULL  |
    | Puffball | Diane | hamster | f    | 1999-03-30 | NULL  |
    +----------+-------+---------+------+------------+-------+
    ## 结合条件来定位雌性狗:
    mysql> select * from pet where species='dog' and sex='f';
    +-------+--------+---------+------+------------+-------+
    | name  | owner  | species | sex  | birth      | death |
    +-------+--------+---------+------+------------+-------+
    | Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
    +-------+--------+---------+------+------------+-------+
    ## 前面的查询使用 AND 逻辑运算符。还有一个 OR 运算符:
    mysql> select * from pet where (species='cat' and sex='m')
        -> or (species='dog' and sex='f');
    +-------+--------+---------+------+------------+-------+
    | name  | owner  | species | sex  | birth      | death |
    +-------+--------+---------+------+------------+-------+
    | Claws | Gwen   | cat     | m    | 1994-03-17 | NULL  |
    | Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
    +-------+--------+---------+------+------------+-------+
    

    注: AND并且 OR可以混合,但 AND优先级高于 OR。如果您同时使用这两个运算符,最好使用括号明确指出条件应如何分组。

    三、检索特定列数据

    ## 只查看 name, birth
    mysql> SELECT name, birth FROM pet;
    +----------+------------+
    | name     | birth      |
    +----------+------------+
    | Fluffy   | 1993-02-04 |
    | Claws    | 1994-03-17 |
    | Buffy    | 1989-05-13 |
    | Fang     | 1990-08-27 |
    | Bowser   | 1989-08-31 |
    | Chirpy   | 1998-09-11 |
    | Whistler | 1997-12-09 |
    | Slim     | 1996-04-29 |
    | Puffball | 1999-03-30 |
    +----------+------------+
     
    ## 要找出谁拥有宠物,请使用此查询:
    mysql> SELECT owner FROM pet;
    +--------+
    | owner  |
    +--------+
    | Harold |
    | Gwen   |
    | Harold |
    | Benny  |
    | Diane  |
    | Gwen   |
    | Gwen   |
    | Benny  |
    | Diane  |
    +--------+
     
    ## 上面的查询有重复的记录,要最小化输出,可以通过添加关键字 DISTINCT 检索每个唯一的输出记录
    mysql> SELECT DISTINCT owner FROM pet;
    +--------+
    | owner  |
    +--------+
    | Benny  |
    | Diane  |
    | Gwen   |
    | Harold |
    +--------+
     
    ## 可以使用WHERE子句将行选择与列选择组合在一起。
    mysql> SELECT name, species, birth FROM pet
        -> WHERE species = 'dog' OR species = 'cat';
    +--------+---------+------------+
    | name   | species | birth      |
    +--------+---------+------------+
    | Fluffy | cat     | 1993-02-04 |
    | Claws  | cat     | 1994-03-17 |
    | Buffy  | dog     | 1989-05-13 |
    | Fang   | dog     | 1990-08-27 |
    | Bowser | dog     | 1989-08-31 |
    +--------+---------+------------+
     
    ## where species in ('dog','cat');
    mysql> SELECT NAME, species, birth FROM pet 
        -> WHERE species IN ('dog','cat');
    +--------+---------+------------+
    | name   | species | birth      |
    +--------+---------+------------+
    | Fluffy | cat     | 1993-02-04 |
    | Claws  | cat     | 1994-03-17 |
    | Buffy  | dog     | 1989-05-13 |
    | Fang   | dog     | 1990-08-27 |
    | Bowser | dog     | 1989-08-31 |
    +--------+---------+------------+
    

    四、排序行数据

    ## 这是动物的生日,按日期排序:
    mysql> SELECT name, birth FROM pet ORDER BY birth;
    +----------+------------+
    | name     | birth      |
    +----------+------------+
    | Buffy    | 1989-05-13 |
    | Bowser   | 1989-08-31 |
    | Fang     | 1990-08-27 |
    | Fluffy   | 1993-02-04 |
    | Claws    | 1994-03-17 |
    | Slim     | 1996-04-29 |
    | Whistler | 1997-12-09 |
    | Chirpy   | 1998-09-11 |
    | Puffball | 1999-03-30 |
    +----------+------------+
     
    ## 默认排序顺序为升序,首先是最小值。要按反向(降序)顺序排序,请将DESC关键字添加到要排序 的列的名称:
    mysql> SELECT name, birth FROM pet ORDER BY birth DESC;
    +----------+------------+
    | name     | birth      |
    +----------+------------+
    | Puffball | 1999-03-30 |
    | Chirpy   | 1998-09-11 |
    | Whistler | 1997-12-09 |
    | Slim     | 1996-04-29 |
    | Claws    | 1994-03-17 |
    | Fluffy   | 1993-02-04 |
    | Fang     | 1990-08-27 |
    | Bowser   | 1989-08-31 |
    | Buffy    | 1989-05-13 |
    +----------+------------+
     
    ## 您可以对多个列进行排序,并且可以按不同方向对不同列进行排序。例如,要按动物类型按升序排序,然后按动物类型中的出生日期按降序排序(最年轻的动物首先),请使用以下查询:
    mysql> SELECT name, species, birth FROM pet
        -> ORDER BY species, birth DESC;
    +----------+---------+------------+
    | name     | species | birth      |
    +----------+---------+------------+
    | Chirpy   | bird    | 1998-09-11 |
    | Whistler | bird    | 1997-12-09 |
    | Claws    | cat     | 1994-03-17 |
    | Fluffy   | cat     | 1993-02-04 |
    | Fang     | dog     | 1990-08-27 |
    | Bowser   | dog     | 1989-08-31 |
    | Buffy    | dog     | 1989-05-13 |
    | Puffball | hamster | 1999-03-30 |
    | Slim     | snake   | 1996-04-29 |
    +----------+---------+------------+
    ## 上面的 DESC 关键字仅适用于紧邻其前面的列名(birth); 它不会影响species列排序顺序。
    

    五、日期计算

    MySQL提供了几个可用于执行日期计算的函数,例如,计算年龄或提取日期的部分。
    要确定每只宠物的年龄,请使用此 TIMESTAMPDIFF()功能。它的参数是您希望表达结果的单位,以及两个可以区分的日期(出生日期,现今日期)。以下查询显示每只宠物的出生日期,当前日期和年龄。一个 别名(age)是用来使得最终输出的列标签更有意义。

    mysql> select name,birth,curdate(),
        -> timestampdiff(year,birth,curdate()) as age
        -> from pet;
    +----------+------------+------------+------+
    | name     | birth      | curdate()  | age  |
    +----------+------------+------------+------+
    | Fluffy   | 1993-02-04 | 2018-08-13 |   25 |
    | Claws    | 1994-03-17 | 2018-08-13 |   24 |
    | Buffy    | 1989-05-13 | 2018-08-13 |   29 |
    | Fang     | 1990-08-27 | 2018-08-13 |   27 |
    | Bowser   | 1989-08-31 | 2018-08-13 |   28 |
    | Chirpy   | 1998-09-11 | 2018-08-13 |   19 |
    | Whistler | 1997-12-09 | 2018-08-13 |   20 |
    | Slim     | 1996-04-29 | 2018-08-13 |   22 |
    | Puffball | 1999-03-30 | 2018-08-13 |   19 |
    +----------+------------+------------+------+
    9 rows in set (0.01 sec)
     
    ## 查询有效,但如果以某种顺序显示行,则可以更轻松地扫描结果。
    ## 这可以通过添加一个ORDER BY name子句来按名称对输出进行排序来完成:
    mysql> select name,birth,curdate(),
        -> timestampdiff(year,birth,curdate()) as age
        -> from pet order by name;
    +----------+------------+------------+------+
    | name     | birth      | curdate()  | age  |
    +----------+------------+------------+------+
    | Bowser   | 1989-08-31 | 2018-08-13 |   28 |
    | Buffy    | 1989-05-13 | 2018-08-13 |   29 |
    | Chirpy   | 1998-09-11 | 2018-08-13 |   19 |
    | Claws    | 1994-03-17 | 2018-08-13 |   24 |
    | Fang     | 1990-08-27 | 2018-08-13 |   27 |
    | Fluffy   | 1993-02-04 | 2018-08-13 |   25 |
    | Puffball | 1999-03-30 | 2018-08-13 |   19 |
    | Slim     | 1996-04-29 | 2018-08-13 |   22 |
    | Whistler | 1997-12-09 | 2018-08-13 |   20 |
    +----------+------------+------------+------+
    9 rows in set (0.00 sec)
     
    ## 以上结果可以通过 order by age 子句来排序
     
    ## 类似的查询可用于确定死亡动物的死亡年龄。可以通过检查death值 是否为NULL。然后,对于那些具有非NULL值的人,计算death和 birth值之间的差值:
    mysql> select name,birth,death,
        -> timestampdiff(year,birth,death) as age
        -> from pet where death is not null order by age;
    +--------+------------+------------+------+
    | name   | birth      | death      | age  |
    +--------+------------+------------+------+
    | Bowser | 1989-08-31 | 1995-07-29 |    5 |
    +--------+------------+------------+------+
    1 row in set (0.00 sec)
    ## 此处查询使用death IS NOT NULL而不是death <> NULL因为 NULL是一个特殊值,无法使用通常的比较运算符进行比较。
    ## <> 代表不等于 ,<=> 代表等于
     
    ## 如果你想知道哪些动物下个月有生日怎么办?对于这种类型的计算,年和日是无关紧要的; 
    ## 您只想提取birth列的月份部分 。MySQL提供了用于提取日期的部分,如一些功能 YEAR(), 
    ## MONTH()和 DAYOFMONTH()。 MONTH()可用于提取月份。
    mysql> select name,birth,month(birth) as birthMonth
        -> from pet
        -> where month(birth)<=>month(curdate());
    +--------+------------+------------+
    | name   | birth      | birthMonth |
    +--------+------------+------------+
    | Fang   | 1990-08-27 |          8 |
    | Bowser | 1989-08-31 |          8 |
    +--------+------------+------------+
    2 rows in set (0.00 sec)
     
    ## 如果当前月份是12月,则会出现一个小的复杂情况。你不能只在月份数字(12)中添加一个并查找月份出生的动物 13,因为没有这样的月份。相反,你寻找1月(月1)出生的动物 。
     
    ## 您可以编写查询,以便无论当前月份是什么,它都可以工作,因此您不必使用特定月份的数字。 DATE_ADD()使您可以将时间间隔添加到给定日期。如果您将值添加一个月CURDATE(),然后使用,则提取月份部分MONTH(),结果将生成查找生日的月份:
     
    mysql> SELECT name, birth FROM pet
        -> WHERE MONTH(birth) = MONTH(DATE_ADD(CURDATE(),INTERVAL 1 MONTH));
     
    ## 完成相同任务的另一种方法是1在使用modulo函数(MOD)将月值包装0为当前值之后,添加1, 以获取当前后一个月:
     
    mysql> SELECT name, birth FROM pet
        -> WHERE MONTH(birth) = MOD(MONTH(CURDATE()), 12) + 1;
     
    ## MONTH()返回1和12之间的数字。并 MOD(something,12)在0和11之间返回一个数字。所以添加1,必须在MOD()之后 .
     
    

    今天就先到这了,有关SQL相关内容在一下链接

    1安装及连接和断开服务器
    2输入查询
    3创建和使用数据库
    4从表中检索信息
    5获取有关数据库和表的信息
    6在批处理模式下使用mysql
    7常见查询示例

  • 相关阅读:
    BZOJ 1040 (ZJOI 2008) 骑士
    BZOJ 1037 (ZJOI 2008) 生日聚会
    ZJOI 2006 物流运输 bzoj1003
    ZJOI 2006 物流运输 bzoj1003
    NOI2001 炮兵阵地 洛谷2704
    NOI2001 炮兵阵地 洛谷2704
    JLOI 2013 卡牌游戏 bzoj3191
    JLOI 2013 卡牌游戏 bzoj3191
    Noip 2012 day2t1 同余方程
    bzoj 1191 [HNOI2006]超级英雄Hero——二分图匹配
  • 原文地址:https://www.cnblogs.com/jason1999/p/11628158.html
Copyright © 2011-2022 走看看