【HW4】

article/2025/10/3 18:42:33

HW4

  • 一、Unsupervised Learning
      • Sharing Parameters
      • Formulation
      • In Practice
      • Various Architectures
      • Application
      • 机器翻译
    • 总结
  • 二、HW4
    • 1、Task
    • 2、数据集分析
      • mapping.json文件
      • metadata.json文件
      • testdata.json文件
    • 3、Dataset
  • 4、Dataloader
    • 5、Model
    • 6、Learning rate schedule
      • LambdaLR
    • 7、Model Function
    • 8、Validate
    • 9、Main function

一、Unsupervised Learning

Sharing Parameters

	你可能会觉得通过当前词汇预测下一个词汇这个约束太弱了,由于不同词汇的搭配千千万万,即便是人也无法准确地给出下一个词汇具体是什么,你可以扩展这个问题,使用10个及以上的词汇去预测下一个词汇,可以帮助得到较好的结果,这里用2个词汇举例,如果是一般是神经网络,我们直接把wi-2和wi-1这两个vector拼接成一个更长的vector作为input即可。但实际上,我们希望和wi-2相连的weight与和wi-1相连的weight是tight在一起的,简单来说就是与的相同dimension对应到第一层hidden layer相同neuron之间的连线拥有相同的weight,在下图中,用同样的颜色标注相同的weight:

在这里插入图片描述
如果我们不这么做,那把同一个word放在wi-2的位置和放在wi-1的位置,得到的Embedding结果是会不一样的。把两组weight设置成相同,可以使wi-2与wi-1的相对位置不会对结果产生影响。除此之外,这么做还可以通过共享参数的方式有效地减少参数量,不会由于input的word数量增加而导致参数量剧增。

Formulation

	假设wi-2的1-of-N编码为xi-2,wi-1的1-of-N编码为xi-1,维数均为|V|,表示数据中的words总数。hidden layer的input为向量z,长度为|Z|,表示降维后的维数, z = W1xi-2 + W2xi-1。其中W1和W2都是|Z|*|V|维的weight matrix,它由|Z|组|V|维的向量构成,第一组|V|维向量与|V|维的xi-2相乘得到z1,第二组|V|维向量与|V|维的xi-2相乘得到z2,...,依次类推。我们强迫让W1=W2=W,此时z=W(xi-2 + xi-1)。因此,只要我们得到了这组参数W,就可以与1-of-N编码x相乘得到word embedding的结果。

在这里插入图片描述

In Practice

那在实际操作上,我们如何保证W1和W2一样呢?

以下图中的wi和wj为例,我们希望它们的weight是一样的:

首先在训练的时候就要给它们一样的初始值。,然后分别计算loss function 对和的偏微分,并对其进行更新。

在这里插入图片描述
这个时候你就会发现,C对wi和wj的偏微分是不一样的,这意味着即使给了wi和wj相同的初始值,更新过一次之后它们的值也会变得不一样,因此我们必须保证两者的更新过程是一致的,即:
在这里插入图片描述
这个时候,我们就保证了wi和wj始终相等:wi和wj的初始值相同,wi和wj的更新过程相同。
在这里插入图片描述
如何去训练这个神经网络呢?注意到这个NN完全是unsupervised,你只需要上网爬一下文章数据直接喂给它即可。比如喂给NN的input是“潮水”和“退了”,希望它的output是“就”,之前提到这个NN的输出是一个由概率组成的vector,而目标“就”是只有某一维为1的1-of-N编码,我们希望minimize它们之间的cross entropy,也就是使得输出的那个vector在“就”所对应的那一维上概率最高。

Various Architectures

除了上面的基本形态,Prediction-based方法还可以有多种变形。
(1)CBOW(Continuous bag of word model)拿前后的词汇去预测中间的词汇
(2)Skip-gram拿中间的词汇去预测前后的词
在这里插入图片描述

Application

机器问答
从得到的word vector里,我们可以发现一些原本并不知道的word与word之间的关系。把word vector两两相减,再投影到下图中的二维平面上,如果某两个word之间有类似包含于的相同关系,它们就会被投影到同一块区域。
在这里插入图片描述

机器翻译

	此外,word vector还可以建立起不同语言之间的联系。如果你要用上述方法分别训练一个英文的语料库(corpus)和中文的语料库,你会发现两者的word vector之间是没有任何关系的,因为Word Embedding只体现了上下文的关系,如果你的文章没有把中英文混合在一起使用,机器就没有办法判断中英文词汇之间的关系。但是,如果你知道某些中文词汇和英文词汇的对应关系,你可以先分别获取它们的word vector,然后再去训练一个模型,把具有相同含义的中英文词汇投影到新空间上的同一个点。接下来遇到未知的新词汇,无论是中文还是英文,你都可以采用同样的方式将其投影到新空间,就可以自动做到类似翻译的效果。

总结

	本节学习了Word Embedding(词嵌入)的知识,其基本思路就是:通过上下文找到这个词的意义,它是无监督学习的(输入一个词,输出一个向量),其基本思路有 Count based(基于统计) 与 Prediction based(基于预测)两种方法。基于统计的主要思想是:两词向量共同出现的频率比较高的话,那么这两个词向量也应该比较相似。而基于预测的方法是,我们要训练一个神经网络,它要做的就是根据当前的word wi-1 ,来预测下一个可能出现的word  wi是什么。

二、HW4

1、Task

做语者辨识任务,一共有600个语者,给了每一个语者的语音feature进行训练,然后通过test_feature进行语者辨识。(本质上还是分类任务Classification)
Simple(0.60824):run sample code and know how to use transformer
Medium(0.70375):know how to adjust parameters of transformer
Strong(0.77750):construct conformer
Boss(0.86500):implement self-attention pooling and additive margin softmax

2、数据集分析

mapping.json文件

在这里插入图片描述
将speakers的id映射到编号0~599,因为一共有600个不同的speaker需要对语音进行分类

metadata.json文件

在这里插入图片描述
存放的是training data,本次实验没有专门设置validation data,需要从training data中划分validation data
n_mels:在对语音数据进行处理时,从每一个时间维度上选取n_mels个维度来表示这个feature
speakers:以key-value形式存放speakers的id和所有feature(每个speaker都有多个feature)
feature_path:这个feature的文件名
mel_len:每一个feature的长度(每一个可能都不一样,后期需要处理)

testdata.json文件

在这里插入图片描述
与metadata形式类似,需要我们进行语者辨识。utterance:话语; 言论

3、Dataset

本次实验的数据来源于 Voxceleb2语音数据集,是真实世界中语者的语音,作业中选取了600个语者,和他们的语音进行训练。

import os
import json
import torch
import random
from pathlib import Path
from torch.utils.data import Dataset
from torch.nn.utils.rnn import pad_sequenceclass myDataset(Dataset):def __init__(self, data_dir, segment_len=128):self.data_dir = data_dirself.segment_len = segment_len#加载从speaker neme到其相应id的映射。mapping_path = Path(data_dir) / "mapping.json"  #mapping_path: Dataset\mapping.jsonmapping = json.load(mapping_path.open()) #mapping: {'speaker2id': {'id00464': 0, 'id00559': 1,self.speaker2id = mapping["speaker2id"] #self.speaker2id: {'id00464': 0, 'id00559': 1, 'id00578': 2, 'id00905': 3,...#加载训练数据的元数据metadata metadata_path = Path(data_dir) / "metadata.json"        metadata = json.load(open(metadata_path))["speakers"] #metadata中存放的key是speaker_id,value是每个speaker的feature和对应长度# 获取speaker的总数。self.speaker_num = len(metadata.keys())self.data = []for speaker in metadata.keys():  #遍历每一个spearker_idfor utterances in metadata[speaker]: #通过speaker_id取出speaker的所有feature和len"""utterances格式:{'feature_path': 'uttr-18e375195dc146fd8d14b8a322c29b90.pt', 'mel_len': 435}{'feature_path': 'uttr-da9917d5853049178487c065c9e8b718.pt', 'mel_len': 490}..."""self.data.append([utterances["feature_path"], self.speaker2id[speaker]])#self.data:[['uttr-18e375195dc146fd8d14b8a322c29b90.pt', 436], #           ['uttr-da9917d5853049178487c065c9e8b718.pt', 436],...#一共600个speaker,436表示第436个speakerdef __len__(self):return len(self.data)def __getitem__(self, index):feat_path, speaker = self.data[index] #feature和speaker编号[0,599]# 加载预处理后的mel-spectrogram.。mel = torch.load(os.path.join(self.data_dir, feat_path)) #加载feature#mel.size():torch.Size([490, 40])# 将mel-spectrogram分割成“segment_len”帧。if len(mel) > self.segment_len: #将feature切片成固定长度#随机获取线段的起点。start = random.randint(0, len(mel) - self.segment_len)  #随机选取切片起始点#获得一个具有“segment_len”帧的分段。mel = torch.FloatTensor(mel[start:start+self.segment_len])#截取长度为segment_len的片段 mel.size():torch.Size([128, 40])else:mel = torch.FloatTensor(mel) #为什么小于segment_len不填充?  填充在dataloader中完成#将说话者id转换为long,以便稍后计算损耗。speaker = torch.FloatTensor([speaker]).long() #将speaker的编号转为long类型return mel, speakerdef get_speaker_number(self):return self.speaker_num  #600

4、Dataloader

主要任务:1.划分验证集 2.将长度小于segment_len的mel进行padding 3.生成dataloader

import torch
from torch.utils.data import DataLoader, random_split
from torch.nn.utils.rnn import pad_sequencedef collate_batch(batch):  #用于整理数据的函数,参数为dataloader中的一个batch#每个批次内的流程特征。"""核对一batch数据。"""mel, speaker = zip(*batch)  #zip拆包,将一个batch中的mel和speaker分开,各自单独形成一个数组# 因为我们是一批一批地训练模型,所以需要在同一个批次中填充特征,使它们的长度相同。#mel中元素长度不相同时,将所有的mel元素填充到最长的元素的长度,填充的值由padding_value决定mel = pad_sequence(mel, batch_first=True, padding_value=-20)    # pad log 10^(-20) 这是非常小的值。# mel: (batch size, length, 40)return mel, torch.FloatTensor(speaker).long()def get_dataloader(data_dir, batch_size, n_workers):"""产生 dataloader"""dataset = myDataset(data_dir)speaker_num = dataset.get_speaker_number()# 将数据集分为训练数据集和验证数据集trainlen = int(0.9 * len(dataset))lengths = [trainlen, len(dataset) - trainlen] trainset, validset = random_split(dataset, lengths) #无覆盖的随机划分训练集和验证集train_loader = DataLoader(trainset,batch_size=batch_size,shuffle=True,drop_last=True,num_workers=n_workers,pin_memory=True,collate_fn=collate_batch,)valid_loader = DataLoader(validset,batch_size=batch_size,num_workers=n_workers,drop_last=True,pin_memory=True,collate_fn=collate_batch,)return train_loader, valid_loader, speaker_num

5、Model

import torch
import torch.nn as nn
import torch.nn.functional as Fclass Classifier(nn.Module):def __init__(self, d_model=160, n_spks=600, dropout=0.1):super().__init__()# 将特征尺寸从输入尺寸投影到d_model中。self.prenet = nn.Linear(40, d_model)#对于文本分类等下游任务,只需要用到Encoder部分即可#nhead:multi_head_attention中head个数#d_model:输入的feature的个数#dim_feedforward:feedforward network的维度#dropout默认0.1self.encoder_layer = nn.TransformerEncoderLayer(d_model=d_model, dim_feedforward=256, nhead=8)# self.encoder = nn.TransformerEncoder(self.encoder_layer, num_layers=2)# 将特征的维度从d_model映射到speaker nums。self.pred_layer = nn.Sequential(nn.Linear(d_model, d_model),nn.ReLU(),nn.Linear(d_model, n_spks),)def forward(self, mels):"""args:mels: (batch size, length, 40)return:out: (batch size, n_spks)"""# out: (batch size, length, d_model)   length=segment_lenout = self.prenet(mels)# out: (length, batch size, d_model)out = out.permute(1, 0, 2) #交换dim=0和dim=1#编码器层期望 (length, batch size, d_model)形式的特征。out = self.encoder_layer(out)# out: (batch size, length, d_model)out = out.transpose(0, 1)  #转置dim=0和dim=1# mean poolingstats = out.mean(dim=1) #可以理解为求平均并去除维度1  stats.size():(batch_size,d_model)# out: (batch, n_spks)out = self.pred_layer(stats)return out

6、Learning rate schedule

当batch设置的比较大的时候通常需要比较大的学习率(通常batch_size和学习率成正比),但在刚开始训练时,参数是随机初始化的,梯度也比较大,这时学习率也比较大,会使得训练不稳定。
warm up 方法就是在最初几轮迭代采用比较小的学习率,等梯度下降到一定程度再恢复初始学习率。


import math
import torch
from torch.optim import Optimizer
from torch.optim.lr_scheduler import LambdaLRdef get_cosine_schedule_with_warmup(optimizer: Optimizer,num_warmup_steps: int,num_training_steps: int,num_cycles: float = 0.5,last_epoch: int = -1,
):"""创建一个学习率随余弦函数值下降的时间表
优化器中的初始lr设置为0,在预热期间,lr在0和之间线性增加.优化器中的初始lr集。参数:
optimizer(:class:` ~ torch . optim . optimizer `):为其调度学习率的优化程序。
num_warmup_steps (:obj:`int `):预热阶段的步骤数。
num_training_steps (:obj:`int `):训练步骤的总数。
num_cycles (:obj:`float ',` optional ',默认为0.5):余弦计划中的波数(默认值是从最大值减少到0跟随半余弦)。
last_epoch (:obj:`int ',` optional ',默认为-1):恢复训练时最后一个时期的索引。
返回:obj:`torch.optim.lr_scheduler。适当的时间表。"""def lr_lambda(current_step):# Warmupif current_step < num_warmup_steps:return float(current_step) / float(max(1, num_warmup_steps))# decadenceprogress = float(current_step - num_warmup_steps) / float(max(1, num_training_steps - num_warmup_steps))return max(0.0, 0.5 * (1.0 + math.cos(math.pi * float(num_cycles) * 2.0 * progress)))return LambdaLR(optimizer, lr_lambda, last_epoch)

pytorch提供了两类函数用于学习率调整

torch.optim.lr_scheduler: 根据学习率更新次数调整学习率
torch.optim.lr_scheduler.ReduceLROnPlateau:根据验证集的评价指标调整学习率

LambdaLR

torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda, last_epoch=-1, verbose=False)# 设置学习率为初始学习率乘以给定lr_lambda函数的值.
new_lr=lr_lambda(last_epoch) * base_lr
#当 last_epoch=-1时, base_lr为optimizer优化器中的lr每次执行 scheduler.step(),  last_epoch=last_epoch +1

optimizer:优化器
lr_lambda:函数或者函数列表
last_epoch:默认为-1,学习率更新次数计数;注意断点训练时last_epoch不为-1
常用的Warmup预热学习率也可以依靠LambdaLR实现


def get_linear_schedule_with_warmup(optimizer, num_warmup_steps, num_training_steps, last_epoch=-1):"""Warmup预热学习率:先从一个较小的学习率线性增加至原来设置的学习率,再进行学习率的线性衰减当 current_step < num_warmup_steps时,new_lr =current_step/num_warmup_steps * base_lr当current_step >= num_warmup_steps时,new_lr =(num_training_steps - current_step) / (num_training_steps -num_warmup_steps) * base_lrArgs:optimizer (:class:`~torch.optim.Optimizer`):The optimizer for which to schedule the learning rate.num_warmup_steps (:obj:`int`):The number of steps for the warmup phase.num_training_steps (:obj:`int`):The total number of training steps.last_epoch (:obj:`int`, `optional`, defaults to -1):The index of the last epoch when resuming training.Return::obj:`torch.optim.lr_scheduler.LambdaLR` with the appropriate schedule."""def lr_lambda(current_step: int):# 自定义函数if current_step < num_warmup_steps:return float(current_step) / float(max(1, num_warmup_steps))return max(0.0, float(num_training_steps - current_step) / float(max(1, num_training_steps - num_warmup_steps)))return LambdaLR(optimizer, lr_lambda, last_epoch)

7、Model Function

调用自定义model的forward部分,每遍历一个batch都要调用一次model_fn

import torchdef model_fn(batch, model, criterion, device):"""Forward a batch through the model."""mels, labels = batch#print("model_fn_mels.size():",mels.size())  # out:torch.Size([16, 128, 40]) [batch_size,segment_len,40]mels = mels.to(device)labels = labels.to(device)outs = model(mels)loss = criterion(outs, labels)# 获取概率最高的说话者id。preds = outs.argmax(1)# 计算准确度。accuracy = torch.mean((preds == labels).float())return loss, accuracy

8、Validate

计算验证集上的准确率

from tqdm import tqdm
import torchdef valid(dataloader, model, criterion, device): """在验证集上验证。"""model.eval()running_loss = 0.0running_accuracy = 0.0#验证集5667个pbar = tqdm(total=len(dataloader.dataset), ncols=0, desc="Valid", unit=" uttr")for i, batch in enumerate(dataloader):with torch.no_grad():loss, accuracy = model_fn(batch, model, criterion, device)running_loss += loss.item()running_accuracy += accuracy.item()pbar.update(dataloader.batch_size)pbar.set_postfix(loss=f"{running_loss / (i+1):.2f}",accuracy=f"{running_accuracy / (i+1):.2f}",)pbar.close()model.train()return running_accuracy / len(dataloader)

9、Main function

开始跑模型,这里与之前的作业有不同的地方。前几个作业是跑完一个epoch也就是完整训练集,再开始跑验证集。这里是跑valid_steps个batch,跑一遍验证集。

from tqdm import tqdmimport torch
import torch.nn as nn
from torch.optim import AdamW
from torch.utils.data import DataLoader, random_splitdef parse_args():"""arguments"""config = {"data_dir": "./Dataset","save_path": "model.ckpt","batch_size": 16,"n_workers": 0,"valid_steps": 2000,"warmup_steps": 1000,"save_steps": 10000,"total_steps":100000,}return configdef main(data_dir,save_path,batch_size,n_workers,valid_steps,warmup_steps,total_steps,save_steps,
):"""Main function."""device = torch.device("cuda" if torch.cuda.is_available() else "cpu")print(f"[Info]: Use {device} now!")train_loader, valid_loader, speaker_num = get_dataloader(data_dir, batch_size, n_workers)train_iterator = iter(train_loader) #iter()生成迭代器,以batch为单位#print("train_iterator:",train_iterator) #<torch.utils.data.dataloader._SingleProcessDataLoaderIter object at 0x000001FD07C558D0>print(f"[Info]: Finish loading data!",flush = True)model = Classifier(n_spks=speaker_num).to(device)criterion = nn.CrossEntropyLoss()optimizer = AdamW(model.parameters(), lr=1e-3)scheduler = get_cosine_schedule_with_warmup(optimizer, warmup_steps, total_steps) #上面定义的warm up函数print(f"[Info]: Finish creating model!",flush = True)best_accuracy = -1.0best_state_dict = Nonepbar = tqdm(total=valid_steps, ncols=0, desc="Train", unit=" step") #train valid_steps个batch再跑验证集for step in range(total_steps): #一共运行total_Steps轮,这里没有epoch的概念# Get datatry:batch = next(train_iterator) #next()返回迭代器的下一个项目,即下一个batch#print("batch[0].size():",batch[0].size())    #out:torch.Size([16, 128, 40]) [batch_size,segment_len,40]       except StopIteration:  # 不指定 default 且迭代器元素耗尽, 将引发 StopIteration 异常train_iterator = iter(train_loader)batch = next(train_iterator)loss, accuracy = model_fn(batch, model, criterion, device) #计算当前batch的loss和acc#print("loss:",loss) #tensor(6.3915, device='cuda:0', grad_fn=<NllLossBackward0>)            batch_loss = loss.item() # loss是张量,item()可以取出张量中的值#print("batch_loss:",batch_loss) #batch_loss: 6.391468048095703batch_accuracy = accuracy.item()# Updata model 反向传播更新参数,每跑一个batch都会更新loss.backward()optimizer.step()scheduler.step()optimizer.zero_grad()# Logpbar.update() #打印当前loss和accpbar.set_postfix(loss=f"{batch_loss:.2f}",accuracy=f"{batch_accuracy:.2f}",step=step + 1,)# Do validationif (step + 1) % valid_steps == 0: #经过valid_steps开始跑验证集pbar.close()valid_accuracy = valid(valid_loader, model, criterion, device) #计算valid_acc# keep the best modelif valid_accuracy > best_accuracy:best_accuracy = valid_accuracybest_state_dict = model.state_dict() #保存模型参数pbar = tqdm(total=valid_steps, ncols=0, desc="Train", unit=" step")# Save the best model so far.if (step + 1) % save_steps == 0 and best_state_dict is not None: #每save_steps轮会保存一次当前最好模型torch.save(best_state_dict, save_path)pbar.write(f"Step {step + 1}, best model saved. (accuracy={best_accuracy:.4f})")pbar.close()if __name__ == "__main__":main(**parse_args())

http://chatgpt.dhexx.cn/article/9wbAVhPV.shtml

相关文章

【微信小程序】--WXML WXSS JS 逻辑交互介绍(四)

&#x1f48c; 所属专栏&#xff1a;【微信小程序开发教程】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#…

微信小程序 | 小程序WXSS-WXML-WXS

&#x1f5a5;️ 微信小程序 专栏&#xff1a;小程序WXSS-WXML-WXS &#x1f9d1;‍&#x1f4bc; 个人简介&#xff1a;一个不甘平庸的平凡人&#x1f36c; ✨ 个人主页&#xff1a;CoderHing的个人主页 &#x1f340; 格言: ☀️ 路漫漫其修远兮,吾将上下而求索☀️ &#x1…

【wx】

.js: //message.js const app getApp() Page({data: {background: #D1EEEE,activeKey: 0,motto: Hello World,userInfo: {},hasUserInfo: false,canIUse: wx.canIUse(button.open-type.getUserInfo),navData: [{text: 首页},{text: 健康},{text: 情感},{text: 职场},{text: 育…

wx-wx-wx-wx-wx-wx-wx-wx-wx-wx-wx

一.⼩程序和H5的区别是什么呢&#xff1f; 运⾏环境&#xff1a;⼩程序基于微信&#xff0c;⽽h5的运行环境是浏览器&#xff0c;所以小程序中没有DOM和BOM的相关API&#xff0c;jquey和一些NPM(2.2.1版本前)包都不能在小程序中使用。小程序可以调用宿主环境/微信提供的微信客…

TensorFlow学习笔记——(11)循环神经网络

文章目录 一、循环核二、循环核时间步展开三、循环计算层四、TF描述循环计算层五、循环计算过程1、RNN实现单个字母预测&#xff08;1&#xff09;过程&#xff08;2&#xff09;完整代码 2、RNN实现输入多个字母&#xff0c;预测一个字母&#xff08;1&#xff09;过程&#x…

【mysql组合查询】

mysql组合查询&#xff1a;将查询出来的值作为表头&#xff0c;并统计类别数量 SELECTa.enterprise_name AS 事业部,sum( IF ( a.alarm_reason 3, a.countt, 0 ) ) AS 正常操作,sum( IF ( a.alarm_reason 4, a.countt, 0 ) ) AS 人员操作,sum(IF( a.alarm_reason NULL, a.c…

mysql 组合查询_mysql组合查询

使用UNION 多数SQL查询都只包含一个或多个表中返回数据的单条SELECT语句。MySQL也允许执行多个查询(多条SELECT语句)&#xff0c;并将结果作为单个查询结果集返回。这些组合查询通常称为并(union) 有两种情况需要使用组合查询&#xff1a; 在单个表查询中从不同的表返回类似结构…

SQL学习十一、组合查询

UNION 操作符用于合并两个或多个 SELECT 语句的结果集。 请注意&#xff0c; 1、UNION 内部的每个 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时&#xff0c;每个 SELECT 语句中的列的顺序必须相同。 即多个 SELECT 语句查询出来的结果集要能合并到一起…

【MySQL】联合查询

目录 1、前言 2、联合查询 3、内连接和外连接 4、案例演示 4.1 查询篮球哥每科的成绩 4.2 查询所有同学的总成绩及邮箱 5、自连接 5.1 显示所有计算机原理成绩比java成绩高的同学 6、子查询 6.1 查询出篮球哥的同班同学 6.2 多行子查询 7、合并查询 1、前言 在实际…

数据库组合查询

在使用数据库的过程中&#xff0c;数据的查询是使用最多的&#xff0c;所以&#xff0c;数据的精确查询是一个很重要的问题。以前的数据查询是最简单的数据查询&#xff0c;也从来没想过组合查询的问题&#xff0c;可是在做机房收费系统的时候&#xff0c;遇到了一个很大的问题…

SQL组合查询知识

大多数SQL查询只从一个或者多表中返回数据都是单个select语句。但是SQL server允许多个select语句执行&#xff0c;它返回的结果是一个结果集&#xff0c;需要使用 union 组合 &#xff0c;这些组合一般称为并&#xff08;union&#xff09;和复合查询&#xff08;compound que…

组合查询

今天我们来学习一下组合查询的方法。什么叫组合查询&#xff0c;就是根据自己选择的内容进行数据查询。我们可以根据单个数据查询&#xff0c;也可以根据多个数据查询我们想要的内容。而我今天要讲的是根据学院、年级、班级还有学号和姓名进行查询的方法&#xff0c;我们首先打…

MySQL入门学习:组合查询

一、组合查询 多数SQL查询都只包含从一个或多个表中返回数据的单条SELECT语句。MySQL也允许执行多个查询&#xff08;多条SELECT语句&#xff09;&#xff0c;并将结果作为单个查询结果集返回。这些组合查询通常称为并&#xff08;union&#xff09;或复合查询&#xff08;comp…

SQL数据库的组合查询和统计查询

数据库的组合查询和统计查询 一、实验目的 对数据库进行组合查询和统计查询 二、实验内容 1、加深对SQL语言查询语句的理解 2、熟练掌握数据查询中的分组统计、计算和组合操作方法。 三、实验要求 在本题下面提交基本操作效果截图。 一&#xff0c;组合查询简单查询。 1、…

组合多个查询

紫色代表一级目录 粉红代表二级目录 蓝色代表三级目录 红色代表关键字 橙色代表说明 单查询与组合查询   单查询实例      使用了操作符UNION    组合查询操作符   UNION     UNION 操作符可以组合两个或多个 SELECT 语句的结果&#xff0c;不包含重复的记录。换…

[Mysql] 组合查询

组合查询可以将多个SELECT结果拼接在一起作为最终结果输出(输出组合成单个查询结果集) 当存在多个查询结果符合条件&#xff0c;需要将多个查询结果进行纵向拼接时&#xff0c;就会用到组合查询 如下图所示&#xff0c;如果需要查出的结果包含表A和表B两个部分&#xff0c;则…

MySQL必知必会:组合查询(Union)

本篇文章主要介绍使用Union操作符将多个SELECT查询组合成一个结果集。本文参考《Mysql必知必会》工作实践融合 组合查询 定义 在大多数开发中&#xff0c;使用一条SELECT查询就会返回一个结果集。如果&#xff0c;我们想一次性查询多条SQL语句&#xff0c;并将每一条SELECT查询…

组合查询——union

文章目录 1.组合查询2.创建组合查询2.1 使用union2.2 union规则2.3 包含或取消重复的行2.4 对组合查询结果排序 1.组合查询 组合查询指的是&#xff1a;在Mysql中执行多个查询&#xff0c;并将结果作为单个查询结果集返回。 这些组合查询通常称为并或复合查询。 以下2种情况&…

【SQL自学打卡|DAY13】——组合查询

前言 ❤欢迎大家阅读我的文章呀❤ 今天是SQL必知必会的最后一块练习。 希望你们在我的文章当中能有所收获&#xff01;&#xff01;&#xff01; SLogan:利用有限的时间&#xff0c;撸起袖子加油干&#xff01; 知识点回顾 内联结&#xff1a;inner join。取两列的交集。 外联…

PyCharm取消波浪线、下划线和中划线

默认情况下&#xff0c;PyCharm中如果有无法错误或者不符合PEP8规范代码下面会有波浪线&#xff0c;语法错误波浪线为红色&#xff08;如下图的第10行&#xff09;&#xff0c;不符合PEP8规范为浅黄色波浪线&#xff08;如下图的第8行&#xff09;&#xff0c;见下图&#xff1…