zoukankan      html  css  js  c++  java
  • 学习查询,需要消化一下

    逛贴吧的时候遇到了这样一个问题

    这样的表结构需要【查询没有学全所有课的同学的学号、姓名、以及未学科目】

    ------------脚本-------------------------

    CREATE TABLE [dbo].[课程表](
        课程id [INT] NULL,
        课程名称 [NVARCHAR](50) NULL,
        讲师id [INT] NULL
    ) ON [PRIMARY]
    
    CREATE TABLE [dbo].成绩表(
        学生id [int] NULL,
        课程id [int] NULL,
        成绩 [int] NULL
    ) ON [PRIMARY]
    
    CREATE TABLE [dbo].学生表(
        学生id [int] NULL,
        学生名称 [nvarchar](50) NULL,
        年龄 [int] NULL,
        性别 [nvarchar](50) NULL
    ) ON [PRIMARY]
    
    
    CREATE TABLE [dbo].讲师表(
        讲师id [int] NULL,
        讲师名称 [nvarchar](50) NULL
    ) ON [PRIMARY]
    
    
    INSERT [dbo].[成绩表] ([学生id], [课程id], [成绩]) VALUES (1, 1, 20)
    GO
    INSERT [dbo].[成绩表] ([学生id], [课程id], [成绩]) VALUES (1, 2, 20)
    GO
    INSERT [dbo].[成绩表] ([学生id], [课程id], [成绩]) VALUES (1, 3, 20)
    GO
    INSERT [dbo].[成绩表] ([学生id], [课程id], [成绩]) VALUES (2, 1, 20)
    GO
    INSERT [dbo].[成绩表] ([学生id], [课程id], [成绩]) VALUES (2, 2, 20)
    GO
    INSERT [dbo].[成绩表] ([学生id], [课程id], [成绩]) VALUES (3, 3, 20)
    GO
    
    
    INSERT [dbo].[讲师表] ([讲师id], [讲师名称]) VALUES (1, N'张老师')
    GO
    INSERT [dbo].[讲师表] ([讲师id], [讲师名称]) VALUES (2, N'李老师')
    GO
    INSERT [dbo].[讲师表] ([讲师id], [讲师名称]) VALUES (3, N'王老师')
    GO
    INSERT [dbo].[讲师表] ([讲师id], [讲师名称]) VALUES (4, N'宋老师')
    GO
    
    INSERT [dbo].[课程表] ([课程id], [课程名称], [讲师id]) VALUES (1, N'语文', 1)
    GO
    INSERT [dbo].[课程表] ([课程id], [课程名称], [讲师id]) VALUES (2, N'数学', 2)
    GO
    INSERT [dbo].[课程表] ([课程id], [课程名称], [讲师id]) VALUES (3, N'英语', 3)
    GO
    INSERT [dbo].[课程表] ([课程id], [课程名称], [讲师id]) VALUES (4, N'体育', 4)
    GO
    
    INSERT [dbo].[学生表] ([学生id], [学生名称], [年龄], [性别]) VALUES (1, N'张三', 12, N'男')
    GO
    INSERT [dbo].[学生表] ([学生id], [学生名称], [年龄], [性别]) VALUES (2, N'李四', 12, N'男')
    GO
    INSERT [dbo].[学生表] ([学生id], [学生名称], [年龄], [性别]) VALUES (3, N'王五', 12, N'男')
    GO
    INSERT [dbo].[学生表] ([学生id], [学生名称], [年龄], [性别]) VALUES (4, N'赵六', 12, N'男')

    解决问题,想法是【构造笛卡尔积】,然后通过【左连接】选出【成绩表】中不存在的【学生id】

      SELECT    s.学生id,
                s.学生名称,
                s.年龄,
                s.性别,
                c.课程id,
                c.课程名称,
                c.讲师id
      FROM      dbo.学生表 s
      LEFT JOIN dbo.课程表 c ON 1=1
      LEFT JOIN dbo.成绩表 ON s.学生id = dbo.成绩表.学生id AND 成绩表.课程id = c.课程id
      WHERE dbo.成绩表.学生id IS NULL

    得到的结果:

    接下来,我用的是SQLServer,所以使用【for xml】来构造

    SELECT B.学生id,
           B.学生名称,
           B.年龄,
           LEFT(B.未学科目, LEN(B.未学科目) - 1) AS 未学科目
      FROM (   SELECT A.学生id,
                      A.学生名称,
                      A.年龄,
                      (   SELECT Z.课程名称 + ','
                            FROM (   SELECT      s.学生id,
                                                 s.学生名称,
                                                 s.年龄,
                                                 s.性别,
                                                 c.课程id,
                                                 c.课程名称,
                                                 c.讲师id
                                       FROM      dbo.学生表 s
                                       LEFT JOIN dbo.课程表 c
                                         ON 1        = 1
                                       LEFT JOIN dbo.成绩表
                                         ON s.学生id   = dbo.成绩表.学生id
                                        AND 成绩表.课程id = c.课程id
                                      WHERE      dbo.成绩表.学生id IS NULL) Z
                           WHERE Z.学生id = A.学生id
                          FOR XML PATH('')) AS 未学科目
                 FROM (   SELECT      s.学生id,
                                      s.学生名称,
                                      s.年龄,
                                      s.性别,
                                      c.课程id,
                                      c.课程名称,
                                      c.讲师id
                            FROM      dbo.学生表 s
                            LEFT JOIN dbo.课程表 c
                              ON 1        = 1
                            LEFT JOIN dbo.成绩表
                              ON s.学生id   = dbo.成绩表.学生id
                             AND 成绩表.课程id = c.课程id
                           WHERE      dbo.成绩表.学生id IS NULL) A
                GROUP BY A.学生id,
                         A.学生名称,
                         A.年龄,
                         A.性别) AS B;

    最后结果

    问题是解决了,但可能效率不高,毕竟笛卡尔积。

  • 相关阅读:
    非常奇怪的VS2005无法调试的问题
    自已写的“动易PowerEasy2006暴库工具”
    用VBA去除Excel工作表保护密码
    mapgis同arcmap之间的数据转换, 投影变换,误差校正,坐标,基础资料,教程的相关信息的汇集
    HDU You Are the One (dp)
    HDU4291 A Short problem
    Mondriaan's Dream(poj2411)
    HDU 4277 USACO ORZ
    求欧拉回路的路径(usaco3.3Riding the Fences)
    poj2923 (状态压缩01背包)
  • 原文地址:https://www.cnblogs.com/ssgdwl/p/12235445.html
Copyright © 2011-2022 走看看