ThinkPHP 数据库操作(七) : 视图查询、子查询、原生查询

视图查询

视图查询可以实现不依赖数据库视图的多表查询,并不需要数据库支持视图,例如:

Db::view('User','id,name')->view('Profile','truename,phone,email','Profile.user_id=User.id')->view('Score','score','Score.user_id=Profile.id')->where('score','>',80)->select();

生成的SQL语句类似于:

SELECT User.id,User.name,Profile.truename,Profile.phone,Profile.email,Score.score 
FROM think_user User
INNER JOIN think_profile Profile ON Profile.user_id=User.id
INNER JOIN think_socre Score ON Score.user_id=Profile.id
WHERE Score.score > 80

  注意,视图查询无需调用 table 和 join 方法,并且在调用 where 和 order 方法的时候只需要使用字段名而不需要加表名。

默认使用INNER join查询,如果需要更改,可以使用:

Db::view('User','id,name')->view('Profile','truename,phone,email','Profile.user_id=User.id','LEFT')->view('Score','score','Score.user_id=Profile.id','RIGHT')->where('score','>',80)->select();

生成的SQL语句类似于:

SELECT User.id,User.name,Profile.truename,Profile.phone,Profile.email,Score.score 
FROM think_user User
LEFT JOIN think_profile Profile ON Profile.user_id=User.id
RIGHT JOIN think_socre Score ON Score.user_id=Profile.id
WHERE Score.score > 80

可以使用别名:

Db::view('User',['id'=>'uid','name'=>'account'])->view('Profile','truename,phone,email','Profile.user_id=User.id')->view('Score','score','Score.user_id=Profile.id')->where('score','>',80)->select();

生成的SQL语句变成:

SELECT User.id AS uid,User.name AS account,Profile.truename,Profile.phone,Profile.email,Score.score 
FROM think_user User
INNER JOIN think_profile Profile ON Profile.user_id=User.id
INNER JOIN think_socre Score ON Score.user_id=Profile.id
WHERE Score.score > 80

可以使用数组的方式定义表名以及别名,例如:

Db::view(['think_user'=>'member'],['id'=>'uid','name'=>'account'])->view('Profile','truename,phone,email','Profile.user_id=member.id')->view('Score','score','Score.user_id=Profile.id')->where('score','>',80)->select();

生成的SQL语句变成:

SELECT member.id AS uid,member.name AS account,Profile.truename,Profile.phone,Profile.email,Score.score 
FROM think_user member
INNER JOIN think_profile Profile ON Profile.user_id=member.id
INNER JOIN think_socre Score ON Score.user_id=Profile.id
WHERE Score.score > 80

 

子查询

首先构造子查询SQL,可以使用下面三种的方式来构建子查询。

1、使用 select 方法

当select方法的参数为false的时候,表示不进行查询只是返回构建SQL,例如:

$subQuery = Db::table('think_user')->field('id,name')->where('id','>',10)->select(false);

生成的subQuery结果为:

SELECT `id`,`name` FROM `think_user` WHERE `id` > 10

2、使用 fetchSql 方法

fetchSql方法表示不进行查询而只是返回构建的SQL语句,并且不仅仅支持select,而是支持所有的CURD查询。

$subQuery = Db::table('think_user')->field('id,name')->where('id','>',10)->fetchSql(true)->select();

生成的subQuery结果为:

SELECT `id`,`name` FROM `think_user` WHERE `id` > 10

3、使用 buildSql 构造子查询

$subQuery = Db::table('think_user')->field('id,name')->where('id','>',10)->buildSql();

生成的subQuery结果为:

( SELECT `id`,`name` FROM `think_user` WHERE `id` > 10 )

调用buildSql方法后不会进行实际的查询操作,而只是生成该次查询的SQL语句(为了避免混淆,会在SQL两边加上括号),然后我们直接在后续的查询中直接调用。

  需要注意的是,使用前两种方法需要自行添加‘括号’。

然后使用子查询构造新的查询:

Db::table($subQuery.' a')->where('a.name','like','thinkphp')->order('id','desc')->select();

生成的SQL语句为:

SELECT * FROM ( SELECT `id`,`name` FROM `think_user` WHERE `id` > 10 ) a WHERE a.name LIKE 'thinkphp' ORDER BY `id` desc

4、使用闭包构造子查询

IN/NOT IN 和 EXISTS/NOT EXISTS 之类的查询可以直接使用闭包作为子查询,例如:

Db::table('think_user')->where('id','IN',function($query){$query->table('think_profile')->where('status',1)->field('id');})->select();

生成的SQL语句是

SELECT * FROM `think_user` WHERE `id` IN ( SELECT `id` FROM `think_profile` WHERE `status` = 1 )
Db::table('think_user')->where(function($query){$query->table('think_profile')->where('status',1);},'exists')->find();

生成的SQL语句为

SELECT * FROM `think_user` WHERE EXISTS ( SELECT * FROM `think_profile` WHERE `status`= 1 )

 

原生查询

Db 类支持原生 SQL 查询操作,主要包括下面两个方法:

query 方法

query 方法用于执行 SQL 查询操作,如果数据非法或者查询错误则返回false,否则返回查询结果数据集(同 select 方法)。

使用示例:

Db::query("select * from think_user where status=1");

  如果你当前采用了分布式数据库,并且设置了读写分离的话,query方法始终是在读服务器执行,因此query方法对应的都是读操作,而不管你的SQL语句是什么。

execute 方法

execute用于更新和写入数据的sql操作,如果数据非法或者查询错误则返回false ,否则返回影响的记录数。

使用示例:

Db::execute("update think_user set name='thinkphp' where status=1");

  如果你当前采用了分布式数据库,并且设置了读写分离的话,execute方法始终是在写服务器执行,因此execute方法对应的都是写操作,而不管你的SQL语句是什么。

参数绑定

支持在原生查询的时候使用参数绑定,包括问号占位符或者命名占位符,例如:

Db::query("select * from think_user where id=? AND status=?",[8,1]);
// 命名绑定
Db::execute("update think_user set name=:name where status=:status",['name'=>'thinkphp','status'=>1]);

 

转载于:https://www.cnblogs.com/swjian/p/10622109.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/463002.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++中的结构体函数

代码 #include "stdafx.h"structTest{ intnum; Test() { printf("11111111"); } Test(inti) { this->numi; } voidfun() { printf("fun"); }};voidmain( void){ Test a(1); …

Linux 查看进程的命令

1、ps ps -x : 只显示当前用户下的所有进程信息 ps -aux : 所有用户下的进程信息 2、top 显示动态的进程信息,5s刷新一次; 3、htop 需要自己安装htop命令,比较牛,个人也只是简单使用过,比top命令快,可…

关于安卓手机在微信浏览器中无法调起相机的原因

最近功在做公司的一个项目,遇到安卓手机在微信浏览器中更换头像无法调起相机的问题,特来此记录一下。 1.微信没有相机权限,开启就行了。 2.〈input type“file” accept“image/*”/〉。图库和相机都能调起。 3.部分冷门手机因系统原因不开放…

使用Microsoft Media Service实现网络影音多媒体应用系列第三篇---技术要点

技术要点解说: l 对Media Service的引用 Imports Microsoft.WindowsMediaServices.Interop Imports System.Runtime.InteropServices 引入以上两个命名空间以后,就可以看到WMSServer这个类,它就是指向Media Service的类。Activator.CreateIn…

SEO新手入门笔记

2019独角兽企业重金招聘Python工程师标准>>> 上个月公司让我给产品网站做SEO,第一次做这种事情,从中学到一些新东西,在这里做一个总结。 什么是SEO SEO是“搜索引擎优化”的简称,目的是提升网站在搜索引擎结果中的排名…

学习进度(4)

记录时间: 第五周 所花时间(包括上课) 10h 代码量(行) 200行 博客量(篇) 0篇 了解到的知识点 深入学习数据库语句 转载于:https://www.cnblogs.com/quxiangjia/p/10676086.html

linux top 命令的结果

PID:进程标志号,是非零正整数USER:进程所有者的用户名PR:进程的优先级别NI:进程的优先级别数值VIRT:进程占用的虚拟内存值RES:进程占用的物理内存值SHR:进程使用的共享内存值S&#…

从语义开始 – 概念、意义、实践

从语义开始 – 概念、意义、实践http://bbs.blueidea.com/thread-2944769-1-1.html 转载于:https://www.cnblogs.com/javashi/archive/2010/05/21/1741019.html

通过Python脚本理解系统进程间通信

from socket import * #导入socket包中的所有内容from time import ctime #导入time包,同时在本地可使用ctime进行调用import os,sys #导入os,sys包HOSTlocalhost#定义主机PORT21567#定义端口BUFSIZ1024 #定义缓冲区ADDR(HOST,PORT) #定义元组tcpSerSoc…

EnterpriseDB Replication,复制Oracle数据测试(1)

EntepriseDB 复制软件目前支持多种数据库到postgre的复制,其基本结构由发布者(Publication)与订阅者(Subscriptions)组成,Replication软件可针对来自不同类型数据库的多个发布者,将其数据复制到多个订阅者(Subscriptions)数据库中。 其可能的几种拓扑结构…

远程桌面登录 Windows Server 2003时提示无权限

2019独角兽企业重金招聘Python工程师标准>>> 登录时弹出提示:要登录到这台远程计算机,您必须被授予允许通过终端服务登录的权限。默认地,"远程桌面用户"组的成员拥有该权限。如果您不是"远程桌面用户"组或其它…

BZOJ 1845三角形面积并

题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id1845 给定100个三角形,求三角形面积并。 戴神模板太可怕。直接调用函数秒掉。思路有点繁琐,不大清楚。贴一个代码。 代码: /* **********************************…

每个大数据工程师都应该知道的OLAP 核心知识点

转载:https://mp.weixin.qq.com/s/I2WqQoGwK7LRrpB4R2pobw 很值得学习的一篇文章,不适用于初学者,适用于中级或者进阶高级的大数据工程师 OLAP 系统广泛应用于 BI, Reporting, Ad-hoc, ETL 数仓分析等场景,本文主要从体系化的角度…

高效便捷地创建单元格数据图表

您能想象折线图、柱状图这些图表被放在一个小小的单元格中的样子吗?Excel 2010的迷你图功能为您提供了这样的便捷体验,让您高效便捷地创建单元格数据图表! 1.打开您想要创建迷你图的Excel工作簿(如果它是Excel 97-200…

CLR Via CSharp读书笔记(7):常量和字段

{TODO:}转载于:https://www.cnblogs.com/thlzhf/archive/2012/12/06/2805424.html

高并发 高负载 网站系统架构 !深入讨论!【转载】

转载于:https://www.cnblogs.com/ifishing/archive/2010/05/26/1744339.html

聊透分布式系统一致性

一、强一致性 一致性大家庭中,虽然细分种类很多,但是实际上只有两大类,其中之一就是强一致性,其具体包含了严格一致性(也叫原子一致性或者线性一致性)和顺序一致性。 严格(原子/线性)一致性 严格一致性代表着,当数据更…

使用jquery打造一个动态的预览产品颜色效果

在浏览一些电子商务网站的时候,选择一件产品的时候,我们经常会看到点击衣服的颜色,同一件衣服的颜色就会切换,让我们觉得真是比较有意思,这样做的效果给用户的体验比较好,今天就给大家分享一下这种效果的实…

@RequestMapping 和 @GetMapping @PostMapping 区别

RequestMapping 和 GetMapping PostMapping 区别 GetMapping是一个组合注解,是RequestMapping(method RequestMethod.GET)的缩写。 PostMapping是一个组合注解,是RequestMapping(method RequestMethod.POST)的缩写。 转自:https://www.c…

C++ 中的 #pragma warning(push) 和 #pragma warning(pop)有什么用

#pragma warning(push)是保存当前的编译器警告状态; #pragma warning(pop)是恢复原先的警告状态。 例如:rocksdb中的一段代码 #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable : 4244) # 禁止compiler警告 // varint32编…