标签:and nvarchar 王老师 sele 笛卡尔积 技术 名称 src XML
逛贴吧的时候遇到了这样一个问题
这样的表结构需要【查询没有学全所有课的同学的学号、姓名、以及未学科目】
------------脚本-------------------------
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;
最后结果
问题是解决了,但可能效率不高,毕竟笛卡尔积。
标签:and nvarchar 王老师 sele 笛卡尔积 技术 名称 src XML
原文地址:https://www.cnblogs.com/ssgdwl/p/12235445.html