通过加入2表查找丢失的记录

时间:2019-08-08 11:07:35

标签: sql sql-server join sql-server-2012 subquery

主表

将显示所有可用的DetailsTable记录,但带有 Ops_Stat = A

的记录除外
+---------+----------+-------+---------+---------+---------------------+-------------------------------------------------------+
| Row_Num | Ops_Stat | RunID | Cust_ID |  Name   |    Date             |                                                       |
+---------+----------+-------+---------+---------+---------------------+-------------------------------------------------------+
|       1 | U        | A123  | AAA1111 | Hulk    | 2019-09-01 01.05.01 | < No need capture this row in expected result         |
|       2 | U        | B456  | AAA1111 | Hulk    | 2019-07-01 01.04.11 |                                                       |
|       3 | U        | C789  | AAA1111 | IronMan | 2019-05-01 01.03.01 |                                                       |
|       4 | A        | D123  | AAA1111 | Spidey  | 2019-01-01 01.02.01 | < Need capture this row and show in expected result   |
|       1 | A        | U489  | BBB2222 | Marvel  | 2019-10-10 02.02.02 | < no need get this if not match of Cust_ID in Details |
|       2 | A        | Y789  | BBB2222 | Marvel  | 2019-09-10 02.02.02 | < no need get this if not match of Cust_ID in Details |
+---------+----------+-------+---------+---------+------------+----------------------------------------------------------------+

详细信息

-如果该字段(名称,原因和更多列)上仅存在更新,则会在此表上显示

-只需捕获 Status ='Comp'

处的记录
+---------+-------+---------+---------+--------+---------------------+--------+---------------------------+
| Row_Num | RunID | Cust_ID |  Name   | Reason |    Date             | Status |                           |
+---------+-------+---------+---------+--------+---------------------+--------+---------------------------+
|       1 | A123  | AAA1111 | Hulk    |        | 2019-09-01 01.05.40 | Pend   | << Ignore status = 'Pend' |
|       2 | B456  | AAA1111 | Hulk    | A      | 2019-07-01 01.04.20 | Comp   |                           |
|       3 | C789  | AAA1111 | IronMan | A      | 2019-05-01 01.03.50 | Comp   |                           |
+---------+-------+---------+---------+--------+---------------------+--------+---------------------------+

预期结果

+----------+---------+---------+---------+--------+-------------------+--------+--------------------------------------+
| Ops_Stat | RunID   | Cust_ID |  Name   | Reason |       Date        | Status |                                      |
+----------+---------+---------+---------+--------+-------------------+--------+--------------------------------------+
| U        | B456    | AAA1111 | Hulk    | A      | 20190701 01.04.20 | Comp   | << take every field in Details table |
| U        | C789    | AAA1111 | IronMan | A      | 20190501 01.03.50 | Comp   | << take every field in Details table |
| A        | D123    | AAA1111 | Spidey  |        | 20190101 01.02.01 |        | << take every field in Master table  |
+----------+---------+---------+---------+--------+-------------------+--------+--------------------------------------+
  1. Cust_ID是在“主表”和“详细信息”表之间进行链接的键
  2. 在预期结果中,需要包括Ops_Stat = A;以及主表和明细表中的Cust_ID是否匹配
  3. 如果在“详细信息”表中没有匹配的Cust_ID,则无需获得预期的结果Ops_Stat = A。
  4. 在预期结果中,需要排除“明细表状态”为“待定”的记录
  5. 请注意日期时间。当Ops_stat = A时,请在MasterTable中获取日期时间,但当Ops_stat不等于A时,请在DetailsTable中获取日期时间

尝试:

select * 
from Master m
left join Details d on m.Cust_ID = d.Cust_ID
where d.Status = 'Comp'

基于上面的尝试,我的发现如下

  1. 主表中的所有记录(状态= pend或com,详细信息表中没有匹配的键,详细信息表中的状态都变为“比较”,而不是“附加” +“比较”

您可以在此处尝试您的代码 SQL Fiddle

2 个答案:

答案 0 :(得分:0)

在这种情况下,我建议将结果集分为两个子查询,即

第一个结果集将取决于Status ='Comp'

select * 
from Master m
inner join Details d 
on m.Cust_ID = d.Cust_ID
where d.Status = 'Comp'

第二个结果集仅包含来自MasterTable的数据

select * 
from Master m 
left join Details d 
on m.cust_Id = d.Cust_ID 
where ops_stat='A'

修改

要连接这两个记录,可以使用UNION ALL,

select m.RowNum, m.Ops_Stat, m.RunID, m.Cust_ID, m.Name, m.DateTime, 
d.RowNum, d.RunID, d.Cust_ID, d.Name, d.Reason, d.DateTime, d.Status
from m
inner join d 
on m.Cust_ID = d.Cust_ID and m.runId=d.runId
where d.Status = 'Comp'

UNION ALL

select m.RowNum, m.Ops_Stat, m.RunID, m.Cust_ID, m.Name, m.DateTime, 
d.RowNum, d.RunID, d.Cust_ID, d.Name, d.Reason, d.DateTime, ISNULL(d.Status,'COMP') 
from m 
left join d 
on m.cust_Id = d.Cust_ID and m.runId=d.runId
where ops_stat='A'

或者您可以将记录插入到第三个临时表中,我不建议您这样做,因为这会花费插入操作的时间。

在SQL小提琴上设置的结果是OUTPUT

答案 1 :(得分:0)

请尝试以下代码。

选择m.Ops_stat,m.RunID,m.Cust_ID,m.Name,d。原因,当isull(d.status,'')=''时,则m.Date else d.date end ddate,d 。状态 来自师父 左联接详细信息d on m.Cust_ID = d.Cust_ID AND m.RunID = d.RunID 其中ISNULL(d.Status,'')<>'挂起'

相关问题