sql联合查询

本文深入解析了SQL中的联合查询方法,包括自然连接、内连接和外连接的使用场景与语法,并详细介绍了COALESCE函数处理空值的技巧。同时,通过案例展示了CASE函数在数据处理和转换中的灵活应用。


SQL语句中的join用法
SQL中join的各种用法

1.自然连接(natural join)
自然连接将表中具有相同名称的列自动进行匹配,自然连接不必指定任何同等连接条件也不能认为指定哪些列需要被匹配,自然连接得到的结果表中,两表中名称相同的列只出现一次。
select * from employee natural join department;

2.内连接(inner join):产生的结果是A和B的交集(相同列里面的相同值)
内连接查询能将左表和右表中能关联起来的数据连接后返回,返回的结果就是两个表中所有相匹配的数据。
select * from TableA as A inner join TableB B on A.PK = B.PK;
select * from TableA as A inner join TableB B on A.PK > B.PK;

3.外连接(outer join)
内连接是要显示两张表的内存,而外连接不要求如此,外连接可以依据连接表保留左表,右表或全部表的行为而分为左外连接右外连接和全连接。
select * from TableA as A left(right/full) join TableB as B on A.PA = B.PK;

Full Join:产生的结果是A和B的并集(如果没有相同的值会用null作为值)

Left Join:产生表A的完全集,而B表中匹配的则有值(没有匹配的则以null值取代)

Right Join:产生表B的完全集,而A表中匹配的则有值(没有匹配的则以null值取代)

COALESCE ( expression,value1,value2……,valuen)
用于对空值的处理
COALESCE()函数的第一个参数expression为待检测的表达式,而其后的参数个数不定,函数将会返回包括expression在内的所有参数中的第一个非空表达式。如果expression不为空值则返回expression,否则判断value1是否是空值,如果value1不为空值则返回value1;否则判断value2是否是空值,如果value2不为空值则返回value2;……以此类推,如果所有的表达式都为空值,则返回NULL。

原文:https://blog.youkuaiyun.com/Jerry_991/article/details/86528459

sql case 函数与详细说明

下面是一个是用case函数来完成这个功能的例子

case具有两种格式。简单case函数和case搜索函数。
–简单case函数

case sex
when ‘1’ then ‘男’
when ‘2’ then ‘女’
else ‘其他’ end
–case搜索函数
case when sex = ‘1’ then ‘男’
when sex = ‘2’ then ‘女’
else ‘其他’ end
这两种方式,可以实现相同的功能。简单case函数的写法相对比较简洁,但是和case搜索函数相比,功能方面会有些限制,比如写判断式。
还有一个需要注意的问题,case函数只返回第一个符合条件的值,剩下的case部分将会被自动忽略。
–比如说,下面这段sql,你永远无法得到“第二类”这个结果

case when col_1 in ( ‘a’, ‘b’) then ‘第一类’
when col_1 in (‘a’) then ‘第二类’
else’其他’ end

下面看一些实例

select country,
sum( case when sex = ‘1’ then
population else 0 end), --男性人口
sum( case when sex = ‘2’ then
population else 0 end) --女性人口
from table_a
group by country;

select sum(population),
case country
when ‘中国’ then ‘亚洲’
when ‘印度’ then ‘亚洲’
when ‘日本’ then ‘亚洲’
when ‘美国’ then ‘北美洲’
when ‘加拿大’ then ‘北美洲’
when ‘墨西哥’ then ‘北美洲’
else ‘其他’ end
from table_a
group by case country
when ‘中国’ then ‘亚洲’
when ‘印度’ then ‘亚洲’
when ‘日本’ then ‘亚洲’
when ‘美国’ then ‘北美洲’
when ‘加拿大’ then ‘北美洲’
when ‘墨西哥’ then ‘北美洲’
else ‘其他’ end;

关于case 二

select
case when salary <= 500 then ‘1’
when salary > 500 and salary <= 600 then ‘2’
when salary > 600 and salary <= 800 then ‘3’
when salary > 800 and salary <= 1000 then ‘4’
else null end salary_class,
count(*)
from table_a
group by
case when salary <= 500 then ‘1’
when salary > 500 and salary <= 600 then ‘2’
when salary > 600 and salary <= 800 then ‘3’
when salary > 800 and salary <= 1000 then ‘4’
else null end;
mysq中横表和纵表的转换有时也是用这种 方法来转换 http://blog.youkuaiyun.com/fysuccess/article/details/40789869

博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

SELECT sum(case WHEN coalesce(t1.total_amount,0)-coalesce(t1.deposit,0)-coalesce(t1.freight,0) >=0 then coalesce(t1.total_amount,0) ELSE (coalesce(t1.deposit,0)+coalesce(t1.freight,0)) END)*0.006  as total
  from pat_medical_record_order t1, pay_record t2
WHERE t1.out_trade_no = ANY (t2.out_trade_nos)
and (t1.order_status).o_value in ('已取消','已驳回') and (t1.pay_status).o_value<>'未付款' and t2.pay_method=3
and to_char(t1.update_time,'YYYY-MM')='2019-05'
-- 已取消 已驳回 0.1146
--0.0528
SELECT
    sum(case WHEN coalesce(t1.total_amount,0)-coalesce(t1.deposit,0)-coalesce(t1.freight,0) >=0
    then coalesce(t1.total_amount,0)
           ELSE (case t2.pay_method WHEN 2 THEN coalesce(t1.total_amount,0) ELSE (coalesce(t1.deposit,0)+coalesce(t1.freight,0)) END ) END)*0.006  as total
  from pat_medical_record_order t1 INNER JOIN pay_record t2
      on t1.out_trade_no = ANY (t2.out_trade_nos)
      LEFT JOIN logistics_sheet l ON t1.id=l.order_id
WHERE
 (t1.order_status).o_value='待收货' and l.print_state='1'
and to_char(t1.update_time,'YYYY-MM')='2019-05'
and t1.access='2';
--0.06048
SELECT
    sum(case WHEN coalesce(t1.total_amount,0)-coalesce(t1.deposit,0)-coalesce(t1.freight,0) >=0
    then coalesce(t1.total_amount,0)
           ELSE (case t2.pay_method WHEN 2 THEN coalesce(t1.total_amount,0) ELSE (coalesce(t1.deposit,0)+coalesce(t1.freight,0)) END ) END)*0.006  as total
  from pat_medical_record_order t1 INNER JOIN pay_record t2
      on t1.out_trade_no = ANY (t2.out_trade_nos)
WHERE
 (t1.order_status).o_value='已完成'
and to_char(t1.update_time,'YYYY-MM')='2019-05'
and t1.access='1';



<think> 首先,用户要求我回答关于SQL联合查询的使用方法和示例。用户参考了三个引用: - 引用[1]:关于SQL查询语句,提到多表联合查询和存储过程,特别是多表联合查询(JOIN Queries)。 - 引用[2]:关于联合查询注入,是SQL注入的一种类型,涉及使用UNION操作。 - 引用[3]:关于UNION联合查询,提供了一个示例使用UNION ALL。 用户明确说:“我想查找SQL联合查询的相关信息,如使用方法、示例等”,并问“请问SQL联合查询的使用方法和示例”。 我需要基于这些引用和用户的问题来回答。用户提到“SQL联合查询”,但从引用来看,似乎混淆了“联合查询”的概念。在SQL中: - **联合查询** 通常指的是使用 `UNION` 操作符来组合多个 `SELECT` 语句的结果。 - **多表联合查询** 可能指的是使用 `JOIN` 操作来连接多个表。 在引用[1]中,它说“多表联合查询(JOIN Queries)”,这指的是 `JOIN`。 在引用[2]和[3]中,提到了“UNION”,这是不同的东西。 用户说“SQL联合查询”,但从上下文,用户可能指的是 `UNION` 操作,因为引用[2]和[3]直接提到它,而引用[1]是 `JOIN`。用户的问题具体说“联合查询”,所以应该是 `UNION`。 在引用[3]中,标题是“UNION 联合查询”,示例是UNION ALL。 所以,我应该聚焦在 `UNION` 操作上,因为用户特意提到了“联合查询”,这与UNION相关。 用户还说:“上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题和你的回答。” 但在这个对话中,这是第一个用户消息,所以没有“上一次的问题”。因此,我应该直接回应当前问题。 系统指令:回答结构清晰,帮助用户逐步解决问题,尽量保证回答真实可靠。使用中文回答。 我的回答需要结构化: - 解释什么是SQL联合查询(UNION)。 - 提供使用方法。 - 展示示例。 - 基于引用添加引用标识,如[^1], [^2], [^3]。 引用提供的信息: - [^1]:提到多表联合查询(JOIN),但用户可能混淆了。我应该澄清区别。 - [^2]:关于UNION注入,但用户问的是使用方法,不是注入。 - [^3]:提供了一个UNION ALL的示例。 所以,在回答中,我可以: 1. 澄清SQL联合查询的类型:可能指UNION操作。 2. 解释UNION的使用方法。 3. 提供示例。 4. 提及安全方面(如注入),但不深入。 最后,系统指令要求“生成相关问题”,所以我需要在回答结尾添加相关问题。 结构回答: 1. **介绍SQL联合查询**:解释UNION操作。 2. **使用方法**:步骤或描述如何使用UNION。 3. **示例**:提供SQL代码示例。 4. **注意事项**:如引用[2]提到的注入风险。 5. **相关问题**:列出几个相关问题。 使用LaTeX格式:行内数学表达式用$...$,但我这里没有数学表达式,所以不需要。独立公式用$$...$$,但本回答可能不需要。 回答中引用的段落末尾添加引用标识。 例如,如果我引用引用[3]的示例,添加[^3]。 最终回答用中文。 大纲: - 开头:SQL联合查询通常指的是使用UNION操作符来合并多个查询结果集。 - 使用方法:UNION用于合并两个或多个SELECT语句的结果,要求列数和数据类型兼容。基本语法:`SELECT ... UNION SELECT ...`。使用UNION ALL来保留重复行。 - 示例:给出类似引用[3]的示例。例如: ```sql SELECT * FROM Table1 UNION SELECT * FROM Table2; ``` 或使用UNION ALL。 - 安全提示:如引用[2]提到,UNION可能被用于SQL注入攻击,因此在实际应用中应注意输入验证[^2]。 - 相关问题生成。 相关问题: 1. UNION和JOIN有什么区别? 2. 如何使用UNION ALL避免去除重复行? 3. SQL注入如何预防? 确保回答真实可靠:基于标准SQL知识。 </think> ### SQL联合查询的使用方法和示例 SQL联合查询通常指的是使用 `UNION` 操作符来合并多个 `SELECT` 语句的结果集,从而返回一个组合后的单一结果集。这与多表联合查询(如 `JOIN` 操作)不同:`UNION` 侧重于纵向合并行(例如,合并两个查询的行),而 `JOIN` 侧重于横向连接列(例如,基于关联键连接两张表)[^1]。在本回答中,我将专注于 `UNION` 查询的使用方法、语法规则和实际示例,确保内容简洁实用。 #### 使用方法 `UNION` 查询的基本规则和步骤如下: 1. **语法格式**: 基本语法为: ```sql SELECT column1, column2, ... FROM table1 UNION [ALL] SELECT column1, column2, ... FROM table2; ``` - `UNION`:自动去除重复行(即结果集唯一)。 - `UNION ALL`:保留所有重复行,性能更高(因为它不检查重复)。 - 每个 `SELECT` 语句的列数、数据类型和顺序必须一致(例如,两个查询的列数相同,且对应列的数据类型兼容)。 2. **使用场景**: - 合并相似结构的数据(如不同表或不同条件下的查询结果)。 - 避免重复数据时用 `UNION`,保留重复数据时用 `UNION ALL`。 - 常用于报表生成、数据聚合或跨表查询。 3. **注意事项**: - **安全风险**:`UNION` 可能被滥用进行SQL注入攻击,攻击者通过添加恶意 `UNION` 语句获敏感数据(如 `UNION SELECT username, password FROM users`)。因此,在实际应用中,必须验证用户输入并使用参数化查询来防御注入[^2]。 - **性能优化**:`UNION ALL` 效率高于 `UNION`,因为省略了去重步骤;避免在大型数据集上频繁使用 `UNION`。 #### 示例 以下示例基于一个简单的数据库场景:假设有两张表 `Students`(学生表)和 `Teachers`(教师表),部分列结构相同(如 `Name` 和 `Age`)。我将演示 `UNION` 和 `UNION ALL` 的典型用法。 **示例1: 基本UNION查询(去除重复行)** 合并 `Students` 和 `Teachers` 表中所有人的姓名(`Name`)和年龄(`Age`),并自动去除重复记录。 ```sql SELECT Name, Age FROM Students UNION SELECT Name, Age FROM Teachers; ``` - **结果说明**:如果 `Students` 中有数据 `('Alice', 20)` 和 `('Bob', 22)`,`Teachers` 中有 `('Carol', 30)` 和 `('Alice', 20)`,则结果只显示唯一的行 `Alice (20)`, `Bob (22)`, `Carol (30)`(重复的 `Alice` 被移除)[^3]。 **示例2: UNION ALL查询(保留重复行)** 合并所有学生的信息,包括重复行(例如,查询不同条件的结果)。 ```sql SELECT Sid, Name, Age FROM Students WHERE Sid BETWEEN 1 AND 3 UNION ALL SELECT Sid, Name, Age FROM Students WHERE Sid BETWEEN 2 AND 5; ``` - **结果说明**:如果 `Students` 表包含 Sid (1-5) 的记录,此查询会合并两个范围(Sid 1-3 和 2-5),保留所有重复行(如 Sid=2 和 Sid=3 会出现在两个集合中)。这是引用[3]中提到的用法[^3]。 **示例3: 多表联合查询(扩展场景)** 如果表结构不完全相同,需要使用别名或常量来对齐列(例如,`Students` 表有 `StudentID` 而 `Teachers` 表有 `TeacherID`,但都显示为ID)。 ```sql SELECT StudentID AS ID, Name FROM Students UNION SELECT TeacherID AS ID, Name FROM Teachers; ``` - **结果说明**:将不同ID列统一为 `ID` 输出,确保列一致性。 #### 总结 `UNION` 查询SQL中强大的工具,用于高效合并数据集。记住:优先使用 `UNION ALL` 提升性能,除非确需去重;同时,务必防范SQL注入风险[^2]。如果您有具体数据库(如MySQLSQL Server),语法可能略有差异,可进一步调整。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值