SQL Full Join 的 Where条件

博客主要讲述SQL需求为损益视图串资产负债视图,用Excel透视表模拟结果后进行SQL查询。强调要慎重选择Where条件,若数据集被CBoard调用,需注意相关项目,因为CBoard会包一层视图,条件决定重复方向。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

SQL需求是损益视图串资产负债视图

用Excel透视表模拟出来的结果就是

 

用SQL查询如下:

当Where条件是左边的视图的时候

select 
        损益视图.年
        ,损益视图.年月
        ,损益视图.期间
        ,损益视图.账簿名称
        ,损益视图.组织编码
        ,损益视图.组织名称    
        ,损益视图.项目名称 损益项目
        ,损益视图.本期发生数 损益本期
        ,资产负债视图.项目名称 资产项目
        ,资产负债视图.年初数 资产年初
        ,资产负债视图.期末数 资产期末
 
                    from 损益视图
                            full join 资产负债视图
                                on 损益视图.年月 = 资产负债视图.年月
                                    and 损益视图.年 =资产负债视图.年
                                    and 损益视图.期间 = 资产负债视图.期间
                                    and 损益视图.账簿名称 = 资产负债视图.账簿名称
                                    and 损益视图.组织编码 = 资产负债视图.组织编码
                    where 损益视图.账簿名称 ='蓝海电子公司主账簿'

 

当Where条件是右边视图的时候

    select 
        损益视图.年
        ,损益视图.年月
        ,损益视图.期间
        ,损益视图.账簿名称
        ,损益视图.组织编码
        ,损益视图.组织名称    
        ,损益视图.项目名称 损益项目
        ,损益视图.本期发生数 损益本期
        ,资产负债视图.项目名称 资产项目
        ,资产负债视图.年初数 资产年初
        ,资产负债视图.期末数 资产期末
 
                    from 损益视图
                            full join 资产负债视图
                                on 损益视图.年月 = 资产负债视图.年月
                                    and 损益视图.年 =资产负债视图.年
                                    and 损益视图.期间 = 资产负债视图.期间
                                    and 损益视图.账簿名称 = 资产负债视图.账簿名称
                                    and 损益视图.组织编码 = 资产负债视图.组织编码
                    --where 损益视图.账簿名称 ='蓝海电子公司主账簿'
                    where 资产负债视图.账簿名称 ='蓝海电子公司主账簿'

 

 所以要慎重选择Where条件,同时如果这个数据集被CBoard调用的时候,那还要注意这些

项目了,因为Cboard会包一层视图,这时候项目就可以变成条件了,条件就决定了重复方向。

select * 
from (
        
    select 
        损益视图.年
        ,损益视图.年月
        ,损益视图.期间
        ,损益视图.账簿名称
        ,损益视图.组织编码
        ,损益视图.组织名称    
        ,损益视图.项目名称 损益项目
        ,损益视图.本期发生数 损益本期
        ,资产负债视图.项目名称 资产项目
        ,资产负债视图.年初数 资产年初
        ,资产负债视图.期末数 资产期末
 
                    from 损益视图
                            full join 资产负债视图
                                on 损益视图.年月 = 资产负债视图.年月
                                    and 损益视图.年 =资产负债视图.年
                                    and 损益视图.期间 = 资产负债视图.期间
                                    and 损益视图.账簿名称 = 资产负债视图.账簿名称
                                    and 损益视图.组织编码 = 资产负债视图.组织编码
) v_cview 

                    --where 损益视图.账簿名称 ='蓝海电子公司主账簿'
                    where 账簿名称 ='蓝海电子公司主账簿'

 

转载于:https://www.cnblogs.com/Bruce_H21/p/10577478.html

<think>在 SQL 中,FULL JOIN(或 FULL OUTER JOIN)是一种连接类型,它返回左表和右表中的所有记录。如果某行在另一个表中没有匹配的行,则结果集中该行的另一个表的部分将包含 NULL 值。 换句话说,FULL JOIN 结合了 LEFT JOIN 和 RIGHT JOIN 的结果。它返回: - 左表中的所有行,即使右表中没有匹配。 - 右表中的所有行,即使左表中没有匹配。 - 当左表和右表中的行匹配时,返回匹配的行。 FULL JOIN 的语法如下: ```sql SELECT column_name(s) FROM table1 FULL OUTER JOIN table2 ON table1.column_name = table2.column_name; ``` 注意:在某些数据库系统中(如 MySQL),并不直接支持 FULL OUTER JOIN。但是,我们可以通过 LEFT JOIN 和 RIGHT JOIN 的 UNION 来模拟 FULL JOIN。 下面是一个示例,假设我们有两个表:`Customers` 和 `Orders`。 **Customers 表:** | CustomerID | CustomerName | |------------|--------------| | 1 | John | | 2 | Mary | | 3 | Alice | **Orders 表:** | OrderID | CustomerID | OrderDate | |---------|------------|-----------| | 1 | 1 | 2020-01-01| | 2 | 2 | 2020-01-02| | 3 | 4 | 2020-01-03| 我们想要获取所有客户以及他们的订单,同时也要获取没有客户的订单和没有订单的客户。 使用 FULL JOIN: ```sql SELECT Customers.CustomerName, Orders.OrderID FROM Customers FULL OUTER JOIN Orders ON Customers.CustomerID = Orders.CustomerID; ``` 结果应该如下(具体顺序可能不同): | CustomerName | OrderID | |--------------|---------| | John | 1 | | Mary | 2 | | Alice | NULL | | NULL | 3 | 由于 MySQL 不支持 FULL JOIN,我们可以用以下方式模拟: ```sql SELECT Customers.CustomerName, Orders.OrderID FROM Customers LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID UNION SELECT Customers.CustomerName, Orders.OrderID FROM Customers RIGHT JOIN Orders ON Customers.CustomerID = Orders.CustomerID; ``` 注意:使用 UNION 会自动去重。如果两个 JOIN 中有重复的行,UNION 会将其合并为一行。如果不想去重,可以使用 UNION ALL,但需要自己处理重复。 解释: - 第一个查询(LEFT JOIN)返回所有客户及其订单(没有订单的客户,订单部分为NULL)。 - 第二个查询(RIGHT JOIN)返回所有订单及其客户(没有客户的订单,客户部分为NULL)。 - 使用 UNION 将两个结果集合并,并去重(因为 FULL JOIN 不应该有重复行,除非有重复数据)。 在支持 FULL JOIN 的数据库(如 PostgreSQL, SQL Server, Oracle等)中,直接使用 FULL JOIN 即可。 下面是一个在 PostgreSQL 中使用的例子: ```sql -- 创建示例表 CREATE TABLE Customers ( CustomerID INT PRIMARY KEY, CustomerName VARCHAR(50) ); CREATE TABLE Orders ( OrderID INT PRIMARY KEY, CustomerID INT, OrderDate DATE ); -- 插入示例数据 INSERT INTO Customers VALUES (1, 'John'), (2, 'Mary'), (3, 'Alice'); INSERT INTO Orders VALUES (1, 1, '2020-01-01'), (2, 2, '2020-01-02'), (3, 4, '2020-01-03'); -- 使用FULL JOIN查询 SELECT Customers.CustomerName, Orders.OrderID, Orders.OrderDate FROM Customers FULL JOIN Orders ON Customers.CustomerID = Orders.CustomerID; ``` 运行上述查询后,会得到以下结果: ``` customername | orderid | orderdate --------------+---------+------------ John | 1 | 2020-01-01 Mary | 2 | 2020-01-02 Alice | NULL | NULL NULL | 3 | 2020-01-03 ``` 注意事项: 1. 在 FULL JOIN 中,ON 条件用于指定连接条件。 2. 如果两个表中的连接列有相同的列名,可以使用 USING 子句简化:`FULL JOIN Orders USING (CustomerID)`。这样在结果中,CustomerID 列只会出现一次。 3. 在 FULL JOIN 中,WHERE 子句可以用于过滤掉那些不匹配的行。例如,如果我们只想看没有匹配的行,可以这样写: ```sql SELECT ... FROM Customers FULL JOIN Orders ON Customers.CustomerID = Orders.CustomerID WHERE Customers.CustomerID IS NULL OR Orders.CustomerID IS NULL; ``` 4. 在模拟 FULL JOIN 时,确保两个子查询的列数和数据类型兼容。 最后,请注意,FULL JOIN 可能会产生大量的结果集,特别是当两个表都很大且匹配行很少时,因为它会返回两个表的笛卡尔积中满足连接条件的部分以及不匹配的部分。因此,在使用时要谨慎,确保理解其含义。 §§相关问题§§: 1. SQL 中除了 FULL JOIN,还有哪些 JOIN 类型? 2. 在 MySQL 中如何模拟 FULL JOIN? 3. FULL JOIN 和 INNER JOIN 有什么区别? 4. 在 FULL JOIN 中,如何只选择那些在另一个表中没有匹配的行?</think>### SQL 中的 FULL JOIN(全外连接) 在 SQL 中,`FULL JOIN`(也称为 `FULL OUTER JOIN`)是一种连接操作,它返回左表和右表的所有记录,无论是否满足连接条件。如果某行在另一个表中没有匹配,则结果中对应列显示为 `NULL`。 #### 基本语法 ```sql SELECT columns FROM table1 FULL JOIN table2 ON table1.column = table2.column; ``` #### 工作原理 1. 返回左表(`table1`)的所有记录 2. 返回右表(`table2`)的所有记录 3. 匹配的记录合并为一行 4. 未匹配的记录用 `NULL` 填充缺失部分 #### 示例代码 假设有两个表:`Employees` 和 `Departments`: **Employees 表** | EmployeeID | Name | DepartmentID | |------------|---------|--------------| | 1 | Alice | 101 | | 2 | Bob | 102 | | 3 | Charlie | NULL | **Departments 表** | DepartmentID | DepartmentName | |--------------|----------------| | 101 | HR | | 102 | IT | | 103 | Finance | 使用 FULL JOIN 查询: ```sql SELECT E.Name AS EmployeeName, D.DepartmentName FROM Employees E FULL JOIN Departments D ON E.DepartmentID = D.DepartmentID; ``` **查询结果**: | EmployeeName | DepartmentName | |--------------|----------------| | Alice | HR | | Bob | IT | | Charlie | NULL | | NULL | Finance | #### 结果说明 - Alice 和 Bob 有匹配的部门 - Charlie 没有部门(DepartmentName 为 NULL) - Finance 部门没有员工(EmployeeName 为 NULL) #### 数据库兼容性注意事项 1. **MySQL 不支持 FULL JOIN** 需用 `LEFT JOIN + RIGHT JOIN + UNION` 模拟: ```sql SELECT E.Name, D.DepartmentName FROM Employees E LEFT JOIN Departments D ON E.DepartmentID = D.DepartmentID UNION SELECT E.Name, D.DepartmentName FROM Employees E RIGHT JOIN Departments D ON E.DepartmentID = D.DepartmentID; ``` 2. **支持 FULL JOIN 的数据库** PostgreSQL, SQL Server, Oracle 等直接支持。 #### 典型应用场景 - 数据完整性检查(找出未关联的记录) - 合并两个数据源(保留所有原始记录) - 数据差异分析
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值