序列化类的校验功能
-局部钩子:必须 validate_字段名
-全局钩子: validate
-ser.is_valid 才做的校验---》入口
-BookSerializer---》Serializer——-》BaseSerializer---》is_valid---》继承了Field
-is_valid 方法
先来到BaseSerializer类中找到is_valid方法
def is_valid(self, *, raise_exception=False):
# self中没有_validated_data,只有执行完后,才有
if not hasattr(self, '_validated_data'):
try:
# 核心---》这一句
# 想看它的源代码,按住ctrl+鼠标点击是不对的---》只能找当前类的父类
#但它真正的执行是,从根上开始找
self._validated_data = self.run_validation(self.initial_data)
except ValidationError as exc:
self._validated_data = {}
self._errors = exc.detail
else:
self._errors = {}
if self._errors and raise_exception:
raise ValidationError(self.errors)
return not bool(self._errors)
-self.run_validation(self.initial_data),不能按住ctrl+鼠标点点击,要从根上开始找
-来到Serializer类中的run_validation方法
def run_validation(self, data=empty):
# 局部钩子
value = self.to_internal_value(data)
try:
# 全局钩子
value = self.validate(value) # BookSerializer只要写了,优先执行它的
except (ValidationError, DjangoValidationError) as exc:
raise ValidationError(detail=as_serializer_error(exc))
return value
局部钩子的分析:-self.to_internal_value(data)---》Serializer类的方法
def to_internal_value(self, data):
for field in fields: #序列化类中写的一个个的字段类的对象列表
# 一个field是name对象,field.field_name字符串 name
# self是谁的对象:序列化类的对象,BookSerializer的对象 validate_name
validate_method = getattr(self, 'validate_' + field.field_name, None)
try:
# 字段自己的校验规则
validated_value = field.run_validation(primitive_value)
if validate_method is not None:
# 局部钩子
validated_value = validate_method(validated_value)
except ValidationError as exc:
errors[field.field_name] = exc.detail
except DjangoValidationError as exc:
errors[field.field_name] = get_error_detail(exc)
except SkipField:
pass
else:
set_value(ret, field.source_attrs, validated_value)
if errors:
raise ValidationError(errors)
return ret
-ser.is_valid---》走局部钩子的代码---》是通过反射获取BookSerializer中写的局部钩子函数,如果写了,就会执行----》走全局钩子代码---》self.validate(value)--->只要序列化类中写了,优先走自己的
assert hasattr(self, 'initial_data'), (
'Cannot call `.is_valid()` as no `data=` keyword argument was '
'passed when instantiating the serializer instance.'
)
东西是我认为的,如果不是就抛异常
等同于if判断+抛异常断定某个东西是我认为的,如果不是就抛异常
等同于if判断+抛异常
def add(a, b):
return a + b
res = add(8, 9)
# assert res == 16, Exception('不等于16')
if not res==16:
raise Exception('不等于16')
print('随便')
视图类:APIView
序列化组件:Serializer,ModelSerializer
drf:Request类的对象
drf:Response
request.data 返回解析之后的请求体数据。类似于Django中标准的request.POST和 request.FILES属性,但提供如下特性:
包含了解析之后的文件和非文件数据
包含了对POST、PUT、PATCH请求方式解析后的数据
利用了REST framework的parsers解析器,不仅支持表单类型数据,也支持JSON数据
request.query_params与Django标准的request.GET相同,只是更换了更正确的名称而
urlencoded
form-data
json
三种都支持
# 总共有三个:JSONParser, FormParser, MultiPartParser
class BookView(APIView):
parser_classes = [JSONParser, FormParser]
# drf的配置,统一写成它
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
# 'rest_framework.parsers.FormParser',
# 'rest_framework.parsers.MultiPartParser',
],
}
-只需要在局部,视图类中,写3个即可
class BookView(APIView):
parser_classes = [JSONParser, FormParser,MultiPartParser]
-优先从视图类中找
-再去项目配置文件找
-再去drf默认的配置中找
return Response({code:100})
响应体的内容,可以字符串,字典,列表
http响应状态码
drf把所有响应码都定义成了一个常量
模板名字,用浏览器访问,看到好看的页面,
-自定制页面
-根本不用
用postman访问,返回正常数据
响应头加数据(后面讲跨域问题再讲)
-headers={'name':'lqz'}
响应编码,一般不用
三个重要的:data,status,headers
默认是两种:纯json,浏览器看到的样子
# 总共有两个个:JSONRenderer,BrowsableAPIRenderer
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
class BookView(APIView):
renderer_classes = [JSONRenderer]
# drf的配置,统一写成它
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
# 'rest_framework.renderers.BrowsableAPIRenderer',
],
}
-只需要在局部,视图类中,写2个即可
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
class BookView(APIView):
renderer_classes = [JSONRenderer,BrowsableAPIRenderer]
大家好,又见面了,我是你们的朋友全栈君。QListWidgetQListWidget类提供了一个基于item的列表小部件。QListWidget是一个方便的类,它提供了类似于QlistView所具有的列表视图,但是具有增加和删除的功能。QListWidget使用内部模型来管理列表中的每个QListWidgetItem。想要有更灵活的列表视图,请使用具有标准模型的QListView类。QlistWidget有两种方法追加数据,一种是一个个增加,还有一种是批量增加:首先我们对QlistWidget做一个初始化:this->setGeometry(100,100,200,200);QListWidget*list=newQListWidget(this);list->setGeometry(50,50,100,100);QlistWidget追加数据方法一//方法一QListWidgetItem*item=newQListWidgetItem;item->setText(“方法一”);list->addItem(item);这种方法最简单,适合少量添加。比如音乐播放器
虽然框架不利于网站优化,但在类似于业务系统的后台中使用的还比较频繁。起初在写的时候,框架的高度与宽度的兼容着实让我很头疼。经过多方面查找资料,及通过自己的实践,特总结以下控制框架宽度与高度的方法。主要是通过以下js控制框架的高度与宽度:<scripttype=”text/javascript”> $(function(){ layoutrezise(); AutoHeight(); }) functionlayoutrezise(){ varheaderH=$(“div#Headbox”).height();//获取头部的高度 varbodyerH=$(window).height()–headerH;//计算内容的高度(不包括头部) $(“div#Bodybox,div#bleftBox,div#brightBox,iframe#leftiframe,iframe#mainframe”).height(bodyerH);//设置主框架的高度 $(“div#brightBox”).width($(window).width()–$(“div#bleftBo
随着区块链市场的不断监管,越来越多的人开始认为区块链是一种底层技术,并开始加入到技术研发的浪潮中。因此,各种区块链技术和各种区块链专利如雨后春笋般涌现。这种监管虽然让区块链摆脱了数字货币的束缚,但是,仅仅停留在技术本身,一味沉迷于区块链技术构建的乌托邦,而不去思考和探索区块链技术的应用,所谓的区块链技术可能会像数字货币一样成为没有根基的空中楼阁。这也是一个错误。探索真正适用的区块链技术,而不是为技术而技术,可能是区块链工业发展真正进入新阶段的重要标志。目前,区块链产业发展正进入一个从技术到落地的新周期。如果区块链的技术和应用之间没有完美的联系,只把技术当作技术,把应用当作应用,那么所谓的区块链可能仍然是一个没有生命的存在。所以,当区块链和数字货币的区分逐渐清晰的时候,真正制约和困扰区块链发展的,不是技术的原始和不成熟,而是地面上的缺失和不足。越来越多的人开始感到区块链的功能和作用不能充分发挥。其中一个很重要的原因就是区块链的应用场景还不够丰富,生态系统还没有真正完整。这种现象不仅没有最大限度地发挥区块链的功能和作用,甚至有可能使区块链再次成为一个利基市场。此时此刻,如何构建一个多元化、
《本文同步发布于“脑之说”微信公众号,欢迎搜索关注~~》研究背景越来越多的研究表明传统的精神疾病诊断体系有很大的局限性。被临床医生诊断为同一种疾病的群体,可能有很大的不一致性。同时被诊断为几种疾病的人,可能表现出同样的临床症状、拥有同样的脑影像异常等。对于同一种的疾病的异质性,以往的研究都没有考虑病人和正常人的差异,只是简单的将病人进行聚类,比如以前我们解读过NatureMedicine的那篇文章《Resting-stateconnectivitybiomarkersdefineneurophysiologicalsubtypesofdepression》。这篇文章最大的创新性有两个:一个是对揭示了精分的2个神经解剖亚型,另一个就是方法的创新,即用一种全新的半监督的聚类方法,来寻找精分的亚型。 那么这是一个什么方法呢?简单点来讲,如下图所示:图1 首先,用监督的非线性学习算法找到病人和正常人的差异,即找到病人和正常人的分界线(面)。由于使用的非线性算法,那么病人和正常人多分解面是一个多面的凸面,那么不同的亚型的病人与正常人的分界凸面是不一样的。接下来,算法再根据这个差异,用无监督的方法
您在此之前可能就已经缓存过模型数据,但是我将向您展示一个使用动态记录模型的更精细的Laravel模型缓存技术,这是我一开始在RailsCasts学习到的技术。使用模型的唯一缓存键,您可以缓存模型(或关联模型)更新时自动更新(以及缓存失效)的模型上的属性和关联,一个好处是访问缓存的数据比在控制器中缓存的数据更具可复用性,因为它在模型上而不是在单个控制器方法中。这是这个技术的要点:假设你有很多个Comment的Article模型,给定下面的Laravelblade模板,你就可以像下面这样访问/article/:id路由时得到评论的数量:<h3$article-comments-count(){{str_plural('Comment',$article-comments-count())</h3复制您可以在控制器中缓存评论的计数,但是当您有多个需要缓存的一次性查询和数据时,控制器会变得非常臃肿难看。使用控制器,访问缓存的数据也不是很方便。我们可以构建一个模板,它仅在文章更新时访问数据库,并且访问该模型的所有代码都可以获取缓存值:<h3$article-
循环结构,复合的赋值运算符8.#include<stdio.h> main() { intsum=10,n=1; while(n<3) { sum=sum-n; n++; } printf(“%d,%d”,n,sum); }复制运行结果为:3,7当循环条件n<3成立的时候,执行循环体{sum=sum-n;n++;}中的语句。循环初值sum为10,n为1;循环条件n<3成立第1次循环:执行sum=sum-n=10-1=9;执行n++,即将n中的值加1,执行后n为2;此时n中的值为2,sum中的值为9,循环条件n<3成立,继续执行循环第2次循环:执行sum=sum-n=9-2=7;执行n++,即将n中的值加1,执行后n为3;输出此时n,sum中的值,即为3,7。需要注意,在printf(“%d,%d”,n,sum);中要求输出的数据彼此间用逗号间隔,因此结果的两个数据间一定要有逗号9.#include<stdio.h> main() { intnum,c; scanf("%d",&num); do{ c=num%1
http://blog.csdn.net/cyblueboy83/article/details/7905862下周参与开发的第三款MMORPG准备上市了,开发了一年左右,前面感觉拼得有点太过了,心身比较疲惫,总结下是太过于急于求成了。近两个月进行了一些调整,感觉状态和开发效率有所提升,在3人的服务器团队的努力下,完成了一些功能并且稳定性还可以。归结下来大概比较有用有几方面。 第一,坚持劳逸结合.无论项目有多急,量有多大,难度有多高,都必须保持健康的身体和良好的精神状态,是项目高效开发的最重要前提。 游戏开发毕竟属于创意行业,一味的长时间加班加点工作很难保持较高的工作效率,特别是服务器这种需要7*24小时长时间稳定运行的服务进程,服务器稳定重于泰山。至少保证每天7小时以上的睡眠,每周坚持一次以上的运动,游泳,球类,爬山之类的运动,根据个人爱好选定。 第二,合理安排时间。即使保证了第一点,每天拥有良好的精神状态,但一天中,人的精力集中程度还是会有差别,这个因人而异。个人早 上9点到11点是精神比较好的时段,建议安排进行项目最重要的部分,例如使用svn工具review服务器组的og日志更改
人生有几万种生活方式,也有远近快慢的优化路线,就像下面这些炫酷的图,伟大的数学家是如何找到最高效的最优化路线呢? 为了玩好这个“最优化”的游戏,成为最棒的“调参师”,数学知识、特别是梯度分析与回归建模尤其重要。 我们会定义一个“损失函数”来评估差距,梯度是指引着我们最小化差距的“方向”。如何更高效找到这个最小化差距的“方向”?想系统了解关于剃度的点点滴滴吗? 1、线性回归建模房子的面积和价格,两者的关系是什么?房子的价格,所涉及的因素很多,房子几室和地段都会决定价格,机器学习中叫做特征或者属性,历史数据,梯度优化,回归建模,曲线拟合。根据历史数据对未来进行预测,给机器装上大脑,这就是机器学习要干的最重要的事情之一。有些规律我们事先并不知道,但不代表它不客观存在。当我们把这个潜在的客观规律找出来,就是regression(回归、追溯)。找出这个规律后,当未来再有新数据进来时,就可以利用这个规律进行预测了。2、梯度分析怎么找潜在的规律?需要数学!讨论一个函数的局部最小值和全局最小值。梯度是什么?复杂函数很难找到全局最小值,无需纠结,但是美丽的凸函数会是个例外。深度下降法为何选择负梯度方
本文由马哥教育面授班22期学员推荐,转载自简书,作者为志朋,内容略经小编改编和加工,观点跟作者无关,最后感谢作者的辛苦贡献与付出。某一天课间,有人提问老师:运维工程师加班真的很严重吗?听说手机得24小时不关机,7*24随时待命,这也太苦逼了点吧……?老鸟回答:没那么夸张,重要的工程不会没有轮值班。没有轮值班说明活儿不重要。不过话说回来,Linux运维工程加班的现象一直是比较普遍的,说大了讲,其实整个互联网行业加班都是很普遍的,好吧!看到这里,作为Linux运维工程师的你,是不是可以平衡点。废话不多说,玩过Linux的人都会知道,Linux中的命令的确是非常多,但是玩过Linux的人也从来不会因为Linux的命令如此之多而烦恼,因为我们只需要掌握我们最常用的命令就可以了。当然你也可以在使用时去找一下man,他会帮你解决不少的问题。然而每个人玩Linux的目的都不同,所以他们常用的命令也就差异非常大,而我主要是用Linux进行C/C++和shell程序编写的,所以常用到的命令可以就会跟一个管理Linux系统的人有所不同。因为不想在使用是总是东查西找,所以在此总结一下,方便一下以后的查看。不
温馨提示:要看高清无码套图,请使用手机打开并单击图片放大查看。Fayson的github:https://github.com/fayson/cdhproject提示:代码块部分可以左右滑动查看噢 1.文档编写目的在前面的文章Fayson讲了《1.如何在RedHat7上安装OpenLDA并配置客户端》、《2.如何在RedHat7中实现OpenLDAP集成SSH登录并使用sssd同步用户》、《3.如何RedHat7上实现OpenLDAP的主主同步》、《4.如何为Hive集成RedHat7的OpenLDAP认证》以及《5.如何为Impala集成Redhat7的OpenLDAP认证》。本篇文章主要介绍如何为Hue集成RedHat7的OpenLDAP认证。内容概述1.测试环境描述2.导入hive用户到OpenLDAP3.Hue集成OpenLDAP4.Hue集成Hive和Impala5.Hue集成验证测试环境1.RedHat7.32.OpenLDAP版本2.4.443.CM和CDH版本为5.13.14.OpenLDAP未启用TLS加密认证5.集群已启用Kerberos前置条件1.OpenLDA
摘要:成为数据极客,建立自己的数据场需要哪些技能呢?遇到普通的数据,通过SQL做分析。如果数据量比较大,可以使用Hadoop等大数据框架处理。在深入挖掘上,可用Python或者R语言进行编程。1数据极客上回书说到,数据科学家是具有数据相关的完整理论和知识的人,自然境界很高。做作一个普通的IT界码农,成为数据科学家需要漫长的过程。那这个……,做不到数据科学家,我们还可以做个数据极客(DataGeek)嘛,挑战数据极限,也是挑战自己的极限。那么,成为数据极客,建立自己的数据场需要哪些技能呢?且不说那高深复杂的理论,仅从实用的角度来分析一下,建立数据场的七个方面。2七大技能2.1SQL与NoSQL技能二维表格数据是最常用形式了,对二维数据的处理分析也是最基本的。传统的SQL工具与大数据环境下的NoSQL工具中,以关系型的MySQL为代表,以文档型的MongoDB为代表,以大数据环境下的Hive代表。这都是数据分析的基础而强大利器,在很多场合下都能快速的解决问题。扩展的,还会有内存型数据库Redis,图数据库Neo4j,还有全文索引的ElasticSearch和Solr,还有Hbase和Cas
这篇文章带你了解怎么整合RabbitMQ服务器,并且通过它怎么去发送和接收消息。我将构建一个springboot工程,通过RabbitTemplate去通过MessageListenerAdapter去订阅一个POJO类型的消息。准备工作15minIDEAmaven3.0在开始构建项目之前,机器需要安装rabbitmq,你可以去官网下载,http://www.rabbitmq.com/download.html,如果你是用的Mac(程序员都应该用mac吧),你可以这样下载:brewinstallrabbitmq复制安装完成后开启服务器:rabbitmq-server复制开启服务器成功,你可以看到以下信息:RabbitMQ3.1.3.Copyright(C)2007-2013VMware,Inc. ####LicensedundertheMPL.Seehttp://www.rabbitmq.com/ #### ##########Logs:/usr/local/var/log/rabbitmq/rabbit@localhost.log ########/usr/local/var/log
2022GoogleI/O大会正式落下帷幕,Flutter作为14个开发者产品和平台中的一款,吸引了来自全球的很多开发者们的关注。随着全国很多地方已经进入夏季,Flutter今年第二季度的开发者调查也如约而至。在此,我们特别邀请大家参与本次开发者调查,本次调查自今日正式开始,并于一周之后截止。 Flutter3和Dart2.17的发布,让Flutter从移动端和Web端,正式来到了对桌面端的稳定支持;Flutter今年也延续了去年的“传统”,发布了一个结合了Flutter和Firebase的Web应用「I/O弹球游戏」,我们也看到社区的成员们玩儿的不亦乐乎。伴随着和Firebase团队的深入合作,现在Flutter已经正式成为Firebase官方支持的平台之一了。与此同时,除了在应用开发上能够让开发者得心应手之外,Flutter还拓展和探索了新的使用场景——「休闲小游戏」,这一类「游戏」有点类似「应用」,比如棋牌、消消乐等,从技术角度说,这类游戏拥有「应用」一样的设计和逻辑,并不像大型游戏应用一样需要投入大量资源,因此,「休闲小游戏」非常值得应用开发者们尝试。为此,Flutter团队
关于链接数据库报错: ERROR1135(HY000):Can'tcreateanewthread(errno11);ifyouarenotoutofavailablememory,youcanconsultthemanualforapossibleOS-dependentbug 看到这个信息会有些迷惑,大概就是要么是内存不够了,要么是遇到OS的bug了。但是通过free命令查看我们的内存是足够的,难道真的就是OS的bug?不会这么巧吧。 既然说的是内存不够了,猜测有可能是某个资源确实是越到了瓶颈,那么执行ulimit看看呢: [mysql@xxxx~]$ulimit-acorefilesize(blocks,-c)unlimiteddatasegsize(kbytes,-d)unlimitedschedulingpriority(-e)0filesize(blocks,-f)unlimitedpendingsignals(-i)127405maxlockedmemory(kbytes,-l)64maxmemorysize(kbytes,-m)unlimi
转自:https://blog.csdn.net/jasonactions/article/details/120776434 1.前言本文主要总结浏览kernelpatch的方法,以此希望促成自己养成阅读patch的习惯。用一个朋友的话说,这样才能更好的融入社区。 2.linux版本发展简介2.1史前时代(0.01~1.0)版本更迭过程为:0.01->0.02->0.10->0.11->0.12->0.95->0.96->0.97.x->0.98.x->0.99.x->1.0 2.2奇偶时代(1.0~2.6.10)版本号用a.b.c表示,其中a为主版本号,b为次版本号,c为修订号版本号变更的原则发生重大改变时升级主版本号,发生非重大改变时升级次版本号;次版本号为奇数表示开发版,次版本号为偶数表示稳定版;稳定版和开发版在修订号上各自升级演进,开发版达到稳定状态时,发布下一个稳定版。版本举例比如1.0.x在尽量不引入新功能的前提下不断升级;同时1.1.x在不断开发新功能的状态下不断升级;当1.1.x的开发到足够稳定时,转变成1.
最近在重新学习数据结构和算法的知识,数据结构和算法问题本身比较枯燥和乏味,而且比较难不容易掌握,但是属于程序员内功的一部分,学习起来容易上瘾。 1.单链表定义 packagealgorithm.datastructors; /** *单向链表 *@authori324779 */ publicclassListNode{ privateintdata; privateListNodenext; publicListNode(intdata){ this.data=data; } publicintgetData(){ returndata; } publicvoidsetData(intdata){ this.data=data; } publicListNodegetNext(){ returnnext; } publicvoidsetNext(ListNodenext){ this.next=next; } } 复制 2,单链表的一些常见操作 packagealgorithm.datastructors; importjava.util.Stack; /**
201623252017-2018-2《程序设计与数据结构》第11周学习总结 教材关键概念摘要 在哈希方法中,元素保存在哈希表中,其在表中的位置由哈希函数确定。 两个元素或关键字映射到表中同一个位置的情形,称为冲突。 将每个元素映射到表中唯一位置的哈希函数称为理想哈希函数。 抽取仅适用元素值或关键字中的一部分来计算保存元素的位置。 在移位折叠方法中,将关键字的各部分加在一起计算下标。 将字符串中各字符按二进制格式进行处理,长度依赖方法和平方取中方法也适用于字符串。 虽然Java为所有的对象提供了hashcode方法,最好还是为特定的类定义一个具体的哈希函数。 处理冲突的链式方法,将哈希表看成是集合的表而不是各独立单元的表。 处理冲突的开放地址方法,即在表中寻找不同于该元素初次哈希到的另一个开放的位置。 装载因子是哈希表扩展之前,表中允许的最大占有百分比。 哈希方法 HashCode是返回对象的哈希码。跟HashMap和Hashtable没多大关系。 HashTable是方法是同步的,HashMap不是。 HashMap中可以存在一条key或value为空的记录,Hasht
1fromlocaleimportatoi 2 3fromkeras.preprocessingimportsequence 4frompandasimportSeries 5 6##!!!!!注意^是异或而不是平方!!!!x**2才是平方 7deflist_basic(): 8A0=dict(zip(('a','b','c','d','e'),(1,2,3,4,5))) 9#A1=range(10)#输出range(0,10) 10#A2=[iforiinA1ifiinA0]#在第一个循环中可以依次从0到9的循环,但ifiinA0中的i只能获取key值而不是键值 11A3=[A0[s]forsinA0]#得到的结果没有顺序,因为字典构建的时候就是乱序的 12#A4=[iforiinA1ifiinA3] 13#A5={i:i*iforiinA1}#构建字典 14#A6=[[i,i*i]foriinA1]#得到嵌套的列表 15print(A0) 16#print(A1) 17print(A3) 18forsinA0: 19print(A0[s]) 20#print(A4) 21#prin
1、查找本机所有关于mysql文件 find/-namemysql 2、删除所有关于mysql文件 rm-rfmysql相关文件以及文件夹 3、解压mysql安装包 tar-zxvfmysql-5.6.44-linux-glibc2.12-x86_64.tar.gz 4、将解压后的文件夹,移动到指定位置 mv mysql-5.6.44-linux-glibc2.12-x86_64/alidata/local/mysql 5、创建mysql用户组,如果存在则不创建 groupaddmysql 6、创建mysql系统用户,放到mysql用户组 useradd-r-gmysqlmysql 7、进入mysql目录 cd/alidata/local/mysql/ 8、更改mysql目录拥有者和群组 chown-Rmysql:mys
1、查询每个部门工资最高的员工信息。 员工表emp 所有列:emp_id,emp_name,dept_id,salary 部门表dept 所有列:dept_id,dept_name. 方法一:先查目标数据,然后和分组查询结果进行in操作。 SELECT e.emp_name,d.dept_name,e.salary FROM empeinnerjoindeptdONe.dept_id=d.dept_id WHERE (e.dept_id,e.salary)IN( SELECT e.dept_id,max(e.salary)ASsalary FROM empeinnerjoindeptdONe.dept_id=d.dept_id groupbydept_id ); 复制 方法二:先查目标数据,然后和分组查询结果进行内连接。 select e.emp_name,e.salary,d.dept_name from empeinnerjoindeptdone.dept_id=d.dept_id innerjoin( select dept_id,