【问题标题】:find missing records by joining 2 table通过加入 2 个表查找丢失的记录
【发布时间】:2019-12-16 01:56:15
【问题描述】:

主表

将显示所有可用 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 是连接 Master 和 Details 表的关键
  2. 在预期结果中,需要包含 Ops_Stat = A 的记录;以及是否在 Master 和 Details 表中匹配 Cust_ID
  3. 在预期结果中,如果Details表中没有Cust_ID匹配,则无需获取Ops_Stat=A。
  4. 在预期结果中,需要排除Details table status = Pend的记录
  5. 请注意日期时间。当 Ops_stat=A 时,取 MasterTable 中的 datetime,但当 Ops_stat 不等于 A 时,取 DetailsTable 中的 datetime

尝试过:

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

根据上面的尝试,我的发现如下

  1. Master 表中的所有记录(无论状态 = pend 还是 com,明细表中没有匹配键,明细表中的状态都变为“Comp”而不是 Pend + Comp

您可以在这里尝试您的代码SQL Fiddle

【问题讨论】:

  • 您是否已经为此编写了任何查询?你在这方面面临什么问题?你能在这里分享那个查询吗?
  • 您的问题到底是什么?您已经列出了一系列要求,但没有提出任何要求。 你的问题是什么?你尝试过什么,为什么没有成功?另外,你是什么意思你“处理10mils”?什么是密耳?
  • @ChetanRanpariya 为我的尝试更新如上。
  • 执行OUTER JOIN,然后在不处理NULL 值的情况下从WHERE 中的连接表中引用a 列,将其转换为隐式INNER JOIN
  • @Larnu 对不起,我不明白你的意思:(

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


【解决方案1】:

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

第一个结果集将取决于 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 fiddle 上的结果集是 OUTPUT

【讨论】:

  • 请告知我如何将它们加入 1 张桌子?
  • dbfiddle.uk/... 使用您的脚本作为基础修改为我的版本(需要排除在详细信息表中不可用的那些 Cust_ID)。但是如果有很多列,这种方法有点“筋疲力尽”。我确实有大约 50 列
  • 如果任何特定列的输出需要更改,那么我们需要提及该列。 首先如果您不想花时间自己编写这些列名,可以尝试从 sys.columns 为给定表生成列列表。 Second 在选择表名的同时按 ALT+F1,它将输出给定表的所有列,然后您可以在所需的查询中选择它们。试一试,让我知道你的发现:)
【解决方案2】:

请尝试下面的代码。

选择 m.Ops_stat,m.RunID,m.Cust_ID,m.Name,d.Reason,case when isnull(d.status,'') = '' then m.Date else d.date end ddate,d 。状态 来自大师 m left join 详细信息 d on m.Cust_ID = d.Cust_ID AND m.RunID = d.RunID 其中 ISNULL(d.Status,'') '挂起'

【讨论】:

  • 没有真正起作用,因为它会显示主表中可用的所有记录
  • 我根据问题中所需的字段更新了我的答案。
  • 没有真正起作用,因为它会显示主表中可用的所有记录。我认为我们应该得到两个表日期,就好像你清楚地看到 RunID = B456, C789 的日期跟随大师的表日期时间一样。
  • 哦,对不起,我错过了日期。我再次更新我的答案
  • 如上所述更新了我的要求。我刚刚意识到我刚才提到的状态都变成了待处理。
猜你喜欢
  • 2021-07-01
  • 2021-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-08
  • 2010-10-15
  • 1970-01-01
相关资源
最近更新 更多