zoukankan      html  css  js  c++  java
  • Data Management Technology(3) -- SQL

    SQL is a very-high-level language, in which the programmer is able to avoid specifying a lot of data-manipulation details that would be necessary in languages like C++.

    What makes SQL viable is that its queries are “optimized” quite well, yielding efficient query executions.

    Core of SQL

    (1) DDL(Data Definition Language), 数据定义语言, used to define database schema

    (2) Query Language 数据查询语言,fetch data from database according to user requirements

    (3) DML(Data Manipulation language), 数据操纵语言,modify database instance, i.e., insert, update or delete data

    (4) DCL(Data Control language),数据控制语言, includes database constraints, user authentication, etc.

    1.Data Definition Language (DDL)

    Defining a Database Schema

    A database schema comprises declarations for the relations (“tables”) of the database.

    Many other kinds of elements may also appear in the database schema, including views, indexes, and triggers, which we’ll introduce later.

    Declaring a Relation

    Simplest form is:

    CREATE TABLE (

     

    );

    And you may remove a relation from the database schema by:

    DROP TABLE ;

    Elements of Table Declarations

    The principal element is a pair consisting of an attribute and a type.

    The most common types are:

    INT or INTEGER (synonyms).

    REAL or FLOAT (synonyms).

    CHAR(n ) = fixed-length string of n characters.

    VARCHAR(n ) = variable-length string of up to n characters.

    DATE and TIME are types in SQL.

    The form of a date value is:

    DATE ‘yyyy-mm-dd’

    The form of a time value is:

    TIME ‘hh:mm:ss’

    with an optional decimal point and fractions of a second following.

    Declaring Keys

    An attribute or list of attributes may be declared PRIMARY KEY or UNIQUE.

    These attribute(s) functionally determine all the attributes of the relation schema.

    There are a few distinctions to be mentioned later.

    Declaring Single-Attribute Keys

    Place PRIMARY KEY or UNIQUE after the type in the declaration of the attribute.

    Example:

    CREATE TABLE Beers (

    name CHAR(20) UNIQUE,

    manf CHAR(20)

    );

    Declaring Multiattribute Keys

    A key declaration can also be another element in the list of elements of a CREATE TABLE statement.

    This form is essential if the key consists of more than one attribute.

    May be used even for one-attribute keys.

    Example:

    CREATE TABLE Sells (

    bar CHAR(20),

    beer VARCHAR(20),

    price REAL,

    PRIMARY KEY (bar, beer)

    );

    PRIMARY KEY Versus UNIQUE

    There exist these distinctions:

    1.There can be only one PRIMARY KEY for a relation, but several UNIQUE attributes.

    2.No attribute of a PRIMARY KEY can ever be NULL in any tuple. But attributes declared UNIQUE may have NULL’s, and there may be several tuples with NULL.

    Other Declarations for Attributes

    Two other declarations we can make for an attribute are:

    1.NOT NULL means that the value for this attribute may never be NULL.

    2.DEFAULT says that if there is no specific value known for this attribute’s component in some tuple, use the stated .

    Example:

    CREATE TABLE Drinkers (

    name CHAR(30) PRIMARY KEY,

    addr CHAR(50)

    DEFAULT ‘123 Sesame St.’,

    phone CHAR(16)

    );

    Adding Attributes

    We may change a relation schema by adding a new attribute (“column”) by:

    ALTER TABLE ADD ;

    Deleting Attributes

    Remove an attribute from a relation schema by:

    ALTER TABLE DROP ;

    2.Queries (Query Language)

    Select-From-Where Statements

    The principal form of a query is:

    SELECT desired attributes

    FROM one or more tables

    WHERE condition about tuples of the tables

    SELECT [ALL|DISTINCT] <目标列表达式>

    ​ [,<目标列表达式>] …

    FROM <表名或视图名>[, <表名或视图名> ] …

    [ WHERE <条件表达式> ]

    [ GROUP BY <列名1> [ HAVING <条件表达式> ] ]

    [ ORDER BY <列名2> [ ASC|DESC ] ];

    Single-relation queries

    Begin with the relation in the FROM clause.

    Apply the selection indicated by the WHERE clause.

    Apply the extended projection indicated by the SELECT clause.

    Operational Semantics

    • To implement this algorithm think of a tuple variable ranging over each tuple of the relation mentioned in FROM.
    • Check if the “current” tuple satisfies the WHERE clause.
    • If so, compute the attributes or expressions of the SELECT clause using the components of this tuple.

    * In SELECT clauses

    • When there is one relation in the FROM clause, * in the SELECT clause stands for “all attributes of this relation.”

    Renaming Attributes

    • If you want the result to have different attribute names, use “AS ” to rename an attribute.

    Handle Duplicates

    • SQL allows duplicates in relations as well as in query results.

    • To force the elimination of duplicates, insert the keyword distinct after select**.**

    • Find the names of all branches in the loan relations, and remove duplicates

      ​ SELECT DISTINCT branch_name FROM loan

    • The keyword all specifies that duplicates not be removed.
      SELECT ALL branch_name FROM loan

    Expressions in SELECT Clauses

    • Any expression that makes sense can appear as an element of a SELECT clause.

      SELECT bar, beer, price * 6 AS priceInYuan FROM Sells;

    • expressions/constants/functions/Attribute alias/…

      constants: SELECT drinker, ‘likes Bud’ AS whoLikesBud FROM Likes WHERE beer = ‘Bud’;

      functions: SELECT Sname,2006-Sage AS 'Year of Birth: ’ ,LOWER(Sdept) FROM Student;

      expressions: SELECT Sname AS NAME,'Year of Birth: ’ AS BIRTH, 2006-Sage AS BIRTHDAY,LOWER(Sdept) AS DEPARTMENT FROM Student;

    Complex Conditions in WHERE Clause

    • attribute names of the relation(s) used in the FROM.

    • comparison operators: =, <>, <, >, <=, >=, between, in

    • apply arithmetic operations: stockprice*2

    • operations on strings (e.g., “||” for concatenation).

    • Lexicographic order on strings.

    • Pattern matching: s LIKE p

      • WHERE clauses can have conditions in which a string is compared with a pattern, to see if it matches.

      • General form:

        LIKE

        NOT LIKE

      • Pattern is a quoted string with % = “any string”; _ = “any character.”

      • ESCAPE character

        When the string contains ‘%’ or ‘_’, you need to use ESCAPE character‘’

    • Special stuff for comparing dates and times.

    • Range comparison: between

      • BETWEEN … AND …
      • NOT BETWEEN … AND …
    • Set operator: in

      • IN <值表>, NOT IN <值表>

        <值表>:用逗号分隔的一组取值

        SELECT Sname,Ssex FROM Student WHERE Sdept IN ( ‘IS’,‘MA’,‘CS’ );

    • Important Points

      • Two single quotes inside a string represent the single-quote (apostrophe).
      • Conditions in the WHERE clause can use AND, OR, NOT, and parentheses in the usual way boolean conditions are built.
      • SQL is case-insensitive. In general, upper and lower case characters are the same, except inside quoted strings.

    Ordering the Display of Tuples

    • Use ‘Order by’ clause to specify the alphabetic order of the query result
      • SELECT DISTINCT customer_name FROM borrower ORDER BY customer_name
    • We may specify desc for descending order or asc for ascending order, for each attribute; ascending order is the default.
    • Note: Order by can only be used as the last part of select statement

    Null Values

    • Tuples in SQL relations can have NULL as a value for one or more components.
    • Meaning depends on context. Two common cases:
      • Missing value : e.g., we know Joe’s Bar has some address, but we don’t know what it is.
      • Inapplicable : e.g., the value of attribute spouse for an unmarried person.
    • Comparing NULL’s to Values
      • The logic of conditions in SQL is really 3-valued logic: TRUE, FALSE, UNKNOWN.
      • When any value is compared with NULL, the truth value is UNKNOWN.
      • But a query only produces a tuple in the answer if its truth value for the WHERE clause is TRUE (not FALSE or UNKNOWN).
    • Three-Valued Logic
      • To understand how AND, OR, and NOT work in 3-valued logic, think of TRUE = 1, FALSE = 0, and UNKNOWN = ½.
      • AND = MIN; OR = MAX, NOT(x) = 1-x.

    Aggregations

    • SUM, AVG, COUNT, MIN, and MAX can be applied to a column in a SELECT clause to produce that aggregation on the column.

    • Also, COUNT(*) counts the number of tuples.

    • 计数

      • COUNT([DISTINCT|ALL] *)
      • COUNT([DISTINCT|ALL] <列名>)
    • 计算总和

      • SUM([DISTINCT|ALL] <列名>)
    • 计算平均值

      • AVG([DISTINCT|ALL] <列名>)
    • 求最大值

      • MAX([DISTINCT|ALL] <列名>)
    • 求最小值

      • MIN([DISTINCT|ALL] <列名>)
    • DISTINCT短语:在计算时要取消指定列中的重复值

      • DISTINCT inside an aggregation causes duplicates to be eliminated before the aggregation.
    • ALL短语:不取消重复值

    • ALL为缺省值

    • NULL never contributes to a sum, average, or count, and can never be the minimum or maximum of a column.

      But if there are no non-NULL values in a column, then the result of the aggregation is NULL.

    • Grouping

      • We may follow a SELECT-FROM-WHERE expression by GROUP BY and a list of attributes.
      • The relation that results from the SELECT-FROM-WHERE is grouped according to the values of all those attributes, and any aggregation is applied only within each group.
      • SELECT beer, AVG(price) FROM Sells GROUP BY beer;
      • Usually, we want aggregations on certain parts of the relation.
    • If any aggregation is used, then each element of the SELECT list must be either:

      1.Aggregated, or

      2.An attribute on the GROUP BY list.

    HAVING Clauses

    • HAVING may follow a GROUP BY clause.
    • If so, the condition applies to each group, and groups not satisfying the condition are eliminated.
    • find the average price of a bar which sells more than 20 beers
      • Select avg(price) from sells group by bar having count(distinct beer) >20

    Extra Materials on Aggregation & Grouping

    • SQL supports several aggregation operations: SUM, MIN, MAX, AVG, COUNT
    • Except COUNT, all aggregations apply to a single attribute:SELECT Count(*) FROM

    不要忘写COUNT (SELECT只能是键)

    Multi-relation queries

    Multirelation Queries

    • Interesting queries often combine data from more than one relation.
    • We can address several relations in one query by listing them all in the FROM clause.
    • Distinguish attributes of the same name by “.”

    Formal Semantics

    Almost the same as for single-relation queries:

    1.Start with the product of all the relations in the FROM clause.

    2.Apply the selection condition from the WHERE clause.

    3.Project onto the list of attributes and expressions in the SELECT clause.

    Operational Semantics

    • Imagine one tuple-variable for each relation in the FROM clause.
      • These tuple-variables visit each combination of tuples, one from each relation.
    • If the tuple-variables are pointing to tuples that satisfy the WHERE clause, send these tuples to the SELECT clause.

    Explicit Tuple-Variables

    Sometimes, a query needs to use two copies of the same relation.

    Distinguish copies by following the relation name by the name of a tuple-variable, in the FROM clause.

    It’s always an option to rename relations this way, even when not essential.

    From Beers(name, manf), find all pairs of beers by the same manufacturer.

    • Do not produce pairs like (Bud, Bud).
    • Produce pairs in alphabetic order.

    对于教学数据库的三个基本表:

    • S(S#, SNAME, AGE, SEX)
    • SC(S#, C#, GRADE)
    • C(C#, CNAME, TEACHER)

    EXERCISE

    试用SQL的查询语句表达下列查询

    --1.检索LIU老师所授课程的课程号和课程名 
    SELECT C#, CName 
    FROM C 
    WHERE TEACHER = 'LIU'
    
    --2.检索学号为S3学生所学课程的课程名与任课老师名 
    SELECT CNAME, TEACHER 
    FROM SC, C 
    WHERE SC.C# = C.C# 
    	AND S#='S3'
    	
    --3.检索至少选LIU老师所授课程中一门课程的女学生姓名 
    SELECT SNAME 
    FROM S, SC, C 
    WHERE SC.C# = C.C# AND SC.S# = S.S#
         AND SEX = 'F'
         AND TEACHER = 'LIU'    
    
    SELECT SNAME 
    FROM S 
    WHERE SEX = 'F'
        AND EXISTS (
            SELECT *
            FROM SC
            WHERE SC.S# = S.S#
            AMD EXISTS (    
            	SELECT *
            	FROM C
            	WHERE C.C# = SC.C#
            	AND TEACHER = 'LIU'
            )
     	)    
    
    --4.检索WANG同学不学的课程的课程号 
    SELECT C# 
    FROM C 
    WHERE NOT EXISTS (
        SELECT *
        FROM S, SC
        WHERE S.S# = SC.S# AND SC.C# = C.C#
        	AND SNAME = 'WANG' 
    )
    	
    --5.检索至少选修两门课程的学生学号,==姓名==
    SELECT DISTINCT X.S#, SNAME
    FROM SC AS X, SC AS Y 
    WHERE X.S# = Y.S# AND X.C#<>Y.C#
    
    --6.检索全部学生都选修的课程的课程号与课程名 
    SELECT C#, CNAME 
    FROM C WHERE NOT EXISTS(
        SELECT *
        FROM S
        WHERE NOT EXISTS(
            SELECT *
            FROM SC
            WHERE SC.S# = S.S# AND SC.C# = C.C#
        ) 
    )
    
    --7.检索选修课程包含刘老师所授课程的学生学号
    
    --8.统计有学生选修的课程门数 
    SELECT COUNT(DISTINCT C#) 
    FROM SC
    
    --9.求选修C4课程的的女学生的平均年龄 
    SELECT AVG(AGE) 
    FROM S, SC
    WHERE S.S# = SC.S# AND C# = 'C4' AND SEX = 'F'
    
    --10.求LIU老师所授课程的每门课程的平均成绩 
    SELECT C.C#, AVG(GRADE) 
    FROM SC, C 
    WHERE SC.C# = C.C# 
    	AND TEACHER = 'LIU' 
    GROUP BY C.C#
    
    --11.统计每门课程的学生选修人数(超过10人的课程才统计)。显示课程号和人数,查询结果按人数降序排列,若人数 相同,按课程号升序排列 
    SELECT C#, COUNT(S#) 
    FROM SC 
    GROUP BY C# 
    HAVING COUNT(*) > 10 
    ORDER BY COUNT(S#) DESC, C#
    
    --12.检索学号比WANG同学大而年龄比他小的学生姓名 
    SELECT SNAME 
    FROM S 
    WHERE S# > ALL(
        SELECT S#
        FROM S
        WHERE SNAME = 'WANG' 
    ) AND AGE < ALL(
        SELECT AGE
        FROM S
        WHERE SNAME = 'WANG' 
    )
    
    --13.在表SC中检索成绩为空值的学生学号和课程号 
    SELECT S#, C#
    FROM SC 
    WHERE GRADE IS NULL
    
    --14.检索姓名以L打头的所有学生的姓名和年龄 
    SELECT SNAME, AGE 
    FROM S 
    WHERE SNAME LIKE 'L%'
    
    --15.求年龄大于女学生平均年龄的男学生姓名和年龄 
    SELECT SNAME, AGE 
    FROM S 
    WHERE SEX = 'M' AND AGE > (
        SELECT AVG(AGE)
        FROM S
        WHERE SEX = 'F' 
    )
    
    --16.求年龄大于所有女学生年龄的男学生姓名和年龄 
    SELECT SNAME, AGE 
    FROM S 
    WHERE SEX = 'M' AND AGE > ALL (
        SELECT AGE
        FROM S
        WHERE SEX = 'F' 
    )
    
    --17.往关系c中插入一个课程元组(’C8’,’VC++’,’BAO’) 
    INSERT INTO C VALUES ('C8', 'VC++', 'BAO')
    
    --18.检索所授每门课程平均成绩均大于80分的教师姓名,并把检索到的值送往另一个已存在的表Faculty(Tname) 
    INSERT INTO Faclty (Tname) 
    SELECT DISTINCT TEACHER FROM (
        SELECT TEACHER, C.C#, AVG(GRADE)
        FROM S, SC    
        WHERE SC.C# = C.C#     
        GROUP BY TEACHER, C.C# 
    ) AS RESULT (
        TEACHER, C#, AVG_GREAD 
    ) AS X WHERE 80 <= ALL (
        SELECT AVG_GREAD     
        FROM RESULT    
        AS Y    
        WHERE Y.TEACHER = X.EACHER 
    )
    
    --19.在SC中删除尚无成绩的选课元组 
    DELETE FROM SC WHERE GRADE IS NULL
    
    --20.把选修LIU老师课程的女同学选课元组全部删除 
    DELETE FROM SC WHERE S# IN (
        SELECT S#    
        FROM S    
        WHERE SEX = 'F'
    ) AND C# IN (
        SELECT C#    
        FROM C    
        WHERE TEACHER = 'LIU' 
    )
    
    --21.把MATHS课不及格的成绩全改为60分 
    UPDATE SC SET GRADE = 60 WHERE GRADE < 60
        AND C# IN (
            SELECT C#        
            FROM C        
            WHERE CNAME = 'MATHS'    
    )
    
    --22.把低于所有课程总平均成绩的男同学成绩提高5% 
    UPDATE SC SET GRADE = GRADE * 1.05 WHERE S# IN (
        SELECT S#    
        FROM S    
        WHERE SEX = 'F' 
    ) AND GRADE < (
        SELECT AVG(GRADE)   
        FROM SC 
    )
    
    --23.在表SC中修改C4课程的成绩,若成绩小于等于70分时提高5%,若成绩大于70分时提高4% 
    UPDATA SC 
    SET GRADE = GRADE*1.04 
    WHERE C# = 'C4'
        AND GRADE > 70 
    UPDATA SC 
    SET GRADE = GRADE * 1.05 
    WHERE C# = 'C4'
         AND GRADE <= 70
    

    针对教学库基本表SC,建立一个视图:

    CREATE VIEW S_GRADE (S#, C_NUM, AVG_GRADE) 
    AS SELECT S#, COUNT(C#), AVG(GRADE) 
    FROM SC 
    GROUP BY S
    

    判断下列查询和更新操作是否允许执行。允许的话写出转换到基本表SC上的相应操作。

    --1. 
    SELECT * FROM S_GRADE 
    --允许 
    SELECT S#,
         COUNT(C#) AS C_NUM,
         AVG(GRADE) AS AVG_GRADE 
    FROM SC 
    GROUP BY S#
    
    --2. 
    SELECT S#, C_NUM 
    FROM S_GRADE 
    WHERE AVG_GRADE > 80 
    --允许
    SELECT S#, COUNT(C#) AS C_NUM 
    FROM SC 
    GROUP BY S# 
    HAVING AVG(GRADE) > 80
    
    --3. 
    SELECT S#, AVG_GRADE 
    FROM S_GRADE 
    WHERE C_NUM > (
        SELECT C_NUM    
        FROM S_GRADE    
        WHERE S# = 'S4' 
    ) 
    --允许 
    SELECT S#, AVG(GRADE) AS AVG_GRADE 
    FROM SC 
    GROUP BY S# 
    HAVING COUNT(C#) > (
        SELECT COUNT (C#)    
        FROM SC    
        GROUP BY S#    
        HAVING S# = 'S4' 
    )
    
    --4. 
    UPDATE S_GRADE 
    SET C_NUM = C_NUM + 2 
    WHERE S# = 'S4' 
    --不允许
    
    --5. 
    UPDATA DELETE 
    FROM S_GRADE 
    WHERE C_NUM > 4 
    --不允许
    

    现有关系模型如下:

    • 学生(学号,姓名, 性别)
    • 课程(课程号,课程名,教师姓名)
    • 选课表(课程号, 学号,成绩)
    --1.检索年龄大于20岁的男生的学号和姓名。 
    SELECT STU_ID, STU_ANME 
    FROM STUDENT AS S 
    WHERE STU_AGE > 20 
    	AND STU_SEX = 'M'
    	
    --2.检索选修了姓刘的老师所教授的课程的女学生的姓名。 
    SELECT STU_NAME 
    FROM STUDENT AS S, STU_COURSE AS SC, COURSE AS C 
    WHERE S.STU_ID = SC.STU_ID 
    	AND SC.COURSE_ID = C.COURSE_ID    
    	AND SEX = 'F' AND TEACHER = '刘'    
    
    --3.检索李想同学不学的课程的课程号和课程名。 
    SELECT COURSE_ID, COURSE_NAME 
    FROM COURSE AS C
    WHERE NOT EXISTS (    
    	SELECT *    
    	FROM STUDENT AS S, STU_COURSE AS SC    
    	WHERE S.STU_ID = SC.STU_ID 
    		AND SC.COURSE_ID = C.COURSE_ID        
    		AND S.STU_NAME = '李明' 
    )
    
    --4.检索至少选修了两门课程的学生的学号。 
    SELECT DISTINCT X.STU_ID, X.STU_NAME 
    FROM STU_COURSE AS X, STU_COURSE AS Y
    WHERE X.STU_ID = Y.STU_ID 
    	AND X.COURSE_ID != Y.COURSE_ID
    	
    --5.求刘老师所教授课程的每门课的平均成绩。 
    SELECT C.COURSE_ID, AVG(SC.GRADE)
    FROM STU_COURSE SC, COURSE C 
    WHERE SC.COURSE_ID = C.COURSE_ID    
    	AND C.COURSE_TEACHER = '刘' 
    GROUP BY C.COURSE_ID
    
    --6.假设不存在重修的情况,写一个视图统计每门课的选修人数(选课人数超过两人的课程才统计)。要求显示课程号和人数, 查询结果按人数降序排列,若人数相同,按课程号升序排列。
    SELECT SC.COURSE_ID, COUNT(SC.STU_ID) 
    FROM STU_COURSE AS SC 
    GROUP BY SC.COURSE_ID 
    HAVING COURSE(SC.STU_ID) > 2 
    ORDER BY 2 DESC, 1
    
    --7.求年龄大于所有女生年龄的男生的姓名和年龄。 
    SELECT S.STU_NAME, S.STU_AGE 
    FROM STUDENT AS S WHERE S.STU_SEX = 'M'
        AND S.STU_AGE > ALL (
            SELECT B.STU_AGE        
            FROM STUDENT AS B        
            WHERE B.STU_SEX = 'F'    
        )     
    
    --8.假定不存在重修的情况,求选修了所有课程的学生的学号姓名。(可以不用相关子查询做) 
    SELECT STUDENT_NUM 
    FROM SC 
    GROUP BY STUDENT_NUM 
    HAVING COUNT(*) = (
        SELECT COUNT(*)    
        FROM COURSE 
    )
    
    --9.写一个视图,统计每门课最高分、最低分、平均分和不及格(小于60分)人数占总人数百分比。(提示:建两个视图来完 成) CREATE VIEW 不及格 AS SELECT 课程号, COUNT(*) AS 人数 FROM 选课 WHERE 成绩 < 60 GROUP BY 课程号
    CREATE VIEW 统计 AS SELECT MAX(成绩), MIN(成绩), AVG(成绩), 不及格.人数/COUNT(*) AS 比率
    FROM 选课, 不及格 
    WHERE 不及格.课程号 = 选课.课程 
    GROUP BY 选课.课程, 不及格.人数
    
    --10.所有女生都选修物理课(已知课程号为001),将她们的物理选课记录插入选课表 INSERT INTO 选课(课程号, 学号) 
    SELECT 001, 学号
    FROM 学生 
    WHERE 性别 = '女'
    
    --11.将物理课的成绩都加20分,但不能超过100分(用两个语句完成) 
    UPDATE 选课 SET 成绩 = 成绩 + 20 WHERE 课程 = '物理' 
    UPDATE 选课 SET 成绩 = 100 WHERE 成绩 > 100
    
    --12.将张老师教的学生都从学生表里删除
    DELETE FROM 学生 WHERE 学号 IN (
        SELECT 学号    
        FROM 选课    
        WHERE 课程号 IN (    
            SELECT 课程号
            FROM 课程        
            WHERE 教师姓名 LIKE '张%'    
        ) 
    )
    
    --13.查询重修次数在2次以上的学生学号,课程号,重修次数 
    SELECT 学号, 课程号, COUNT(*) 
    FROM SC
    GROUP BY 学号, 课程号 
    HAVING COUNT(*) >= 2 
    
    --14.将学生的重修课程成绩都改成60分 
    UPDATE 选课 SET 成绩 = 60 WHERE EXISTS (
        SELECT *    
        FROM 选课 B    
        WHERE 选课.学号 = B.学号 AND 选课.课程 = b.课程    
        GROUP BY 学号, 课程    
        HAVING COUNT(*) >= 2 
    )
    
    --15.查询重修学生人数最多的课程号,课程名,教师姓名 
    SELECT 课程 
    FROM 选课 
    GROUP BY 学号, 课程 
    HAVING COUNT(*) >= ALL (
        SELECT COUNT(*)     
        FROM 选课    
        GROUP BY 学号, 课程    
        HAVING COUNT(*) > 0 
    )
    
    USE [Shop] 
    GO
    
    ALTER TABLE Order1 ADD CONSTRAINT OID PRIMARY KEY(OID)
    
    --查询与CID=1的顾客同一个城市的所有顾客ID 
    SELECT c1.CID 
    FROM Customer c1 
    WHERE c1.City = (
            SELECT DISTINCT c2.City        
            FROM Customer c2        
            WHERE c2.CID = 1 
    )
    
    --查询购买过所有省份(Food表中出现过的City)的食物的顾客ID 
    SELECT Customer.CID 
    FROM Customer 
    INNER JOIN Order1 ON Order1.CID = Customer.CID 
    INNER JOIN Food ON Food.FID = Order1.FID 
    GROUP BY Customer.CID 
    HAVING COUNT(DISTINCT Customer.City) = (
        SELECT COUNT(DISTINCT City)    
        FROM Food 
    )
    
    --查询至少购买过ID为13的顾客买过的全部食物的顾客ID 
    SELECT DISTINCT C1.CID 
    FROM Customer C1 
    WHERE NOT EXISTS (
        SELECT *    
        FROM Customer C2    
        WHERE C2.CID = 13         
        AND NOT EXISTS (
             SELECT * 
             FROM Customer C3            
             WHERE C3.CID = C1.CID 
             	AND C3.CID = C2.CID
        ) 
    )
    
    --建立购买过重庆或四川食物的顾客视图Shu-view(包含Customer中CID,City) 
    CREATE VIEW Shu_view 
    AS SELECT DISTINCT Customer.CID, Customer.City 
    FROM Customer 
    INNER JOIN Order1 ON Order1.CID = Customer.CID 
    INNER JOIN Food ON Food.FID = Order1.FID 
    WHERE EXISTS(
        SELECT *    
        FROM Food    
        WHERE Food.City = '重庆' 
    ) OR EXISTS (
        SELECT *    
        FROM Food    
        WHERE Food.City = '四川'
    )
    
    --运用视图Shu-view挑选出订单总消费最高的顾客CID 
    SELECT Shu_view.CID 
    FROM Shu_view 
    INNER JOIN Order1 ON Order1.CID = Shu_view.CID 
    INNER JOIN Food ON Food.FID = Order1.FID 
    GROUP BY Shu_view.CID
    HAVING SUM(Quantity * Price) >= ALL (
        SELECT SUM(Quantity *Price)    
        FROM Shu_view    
        INNER JOIN Order1 ON Order1.CID = Shu_view.CID    
        INNER JOIN Food ON Food.FID = Order1.FID    
        GROUP BY Shu_view.CID 
    )
    
    --不能,“因为视图或函数 'Shu_view' 包含聚合、DISTINCT 或 GROUP BY 子句或者 PIVOT 或 UNPIVOT 运算符,所 以无法进行更新。”
    --建立男性顾客的视图Male-view    
    --(包含Customer中CID,City); 
    --并要求对该视图进行的更新操作只涉及男性顾客。    
    --(WITH CHECK OPTION,并考虑视图的可扩充性) 
    CREATE VIEW Male_view 
    AS SELECT Customer.CID, Customer.Gender, Customer.City 
    FROM Customer 
    WHERE Gender = '男' 
    WITH CHECK OPTION
    
    --向视图Male-view加入表项(17,湖南),并观察此时Customer表中新增表项的性别是什么? INSERT INTO Male_view(CID, Gender, City) VALUES ('17', '男', '湖南')
    --用对应的语句为以下的列创建恰当的索引,并写出相应的理由 --1.Food.Price 频繁修改索引列 
    CREATE INDEX idx_Price ON Food(Price ASC) 
    --2.Customer.Gender 不应该建立索引,因为只有不少数不同的值) --3.Order.OID 主键,应该建立索引 --如果原先已经设定主键,则无需创建聚类索引(CREATE UNIQUE  CLUSTERED),因为在定义主键的时候,会自动添加索 引。“例如报错:无法对表 'Customer' 创建多个聚集索引。请在创建新聚集索引前删除现有的聚集索引 'CID'。” 
    CREATE UNIQUE  CLUSTERED INDEX idx_OID ON Order1(OID ASC)
    
    CREATE INDEX idx_OID ON Order1(OID ASC)
    

    写出表的定义语句(考虑键和关系)[^ 直接导入的表格将会没有主键或外键,需要自己新建查询进行约束]

    --修改数据类型 
    AlTER TABLE Customer ALTER COLUMN CID int NOT NULL 
    AlTER TABLE Customer ALTER COLUMN Gender varchar(10) 
    AlTER TABLE Customer ALTER COLUMN City varchar(255)
    AlTER TABLE Food ALTER COLUMN FID int NOT NULL
    AlTER TABLE Food ALTER COLUMN Name varchar(255) NOT NULL
    AlTER TABLE Food ALTER COLUMN City varchar(255)
    AlTER TABLE Food ALTER COLUMN Price INT NOT NULL
    
    ALTER TABLE Orders ALTER COLUMN OID INT NOT NULL 
    ALTER TABLE Orders ALTER COLUMN CID INT NOT NULL 
    ALTER TABLE Orders ALTER COLUMN FID INT NOT NULL 
    ALTER TABLE Orders ALTER COLUMN Quantity INT NOT NULL
    
    --增加主键 
    AlTER TABLE Customer ADD CONSTRAINT CID PRIMARY KEY(CID) 
    AlTER TABLE Food ADD CONSTRAINT FID PRIMARY KEY(FID) 
    ALTER TABLE Orders ADD CONSTRAINT OID PRIMARY KEY(OID)
    
    
  • 相关阅读:
    SciPy
    时间序列
    bytes 与 str 转换
    tensorflow
    Python3+Cuda+Cudnn+GPU
    TensorFlow models
    saltstack
    docker
    分布式文件系统
    创建RHCS集群环境 创建高可用Apache服务
  • 原文地址:https://www.cnblogs.com/wojiaobuzhidao/p/11071468.html
Copyright © 2011-2022 走看看