在MySQL中查找并用正确的数据替换重复项

在MySQL中查找并用正确的数据替换重复项,mysql,sql,Mysql,Sql,下表中有重复的家庭ID,但家庭成员的数量不同: tbl_family +------------+--------------+---------+ | familyID | Members | Location| +------------+--------------+---------+ | 100 | 3 | xyz | | 100 | 4 | xyz | | 101 |

下表中有重复的家庭ID,但家庭成员的数量不同:

tbl_family

+------------+--------------+---------+
| familyID   | Members      | Location|
+------------+--------------+---------+
|      100   | 3            |    xyz  |
|      100   | 4            |    xyz  |
|      101   | 1            |    abc  |
|      101   | 2            |    abc  |
|      102   | 5            |    efg  |
|      103   |              |    hij  |
+------------+--------------+---------+
我还有第二张表,在那里我们验证了重复的家庭成员的正确数量

tbl_verifier

+------------+--------------+---------+
| familyID   | Members      | Location|
+------------+--------------+---------+
|      100   | 3            |    xyz  |
|      101   | 2            |    abc  |
+------------+--------------+---------+
我想在mysql中创建一个视图,该视图将显示没有重复项的族,并使用已验证的族成员数维护该行。结果应如下所示:

tbl_results
+------------+--------------+---------+
| familyID   | Members      | Location|
+------------+--------------+---------+
|      100   | 3            |    xyz  |
|      101   | 2            |    abc  |
|      102   | 5            |    efg  |
|      103   |              |    hij  |
+------------+--------------+---------+
我正在把这个问题分成几个步骤。我想先选择所有具有匹配成员的,然后选择那些具有空成员的

/* Step 1: Select only those that are matching family members count in 
verifier and family */

select *
from tbl_family f
inner join
tbl_verifier v
ON f.familyID = v.familyID
WHERE f.Members = v.Members;

/* Step 2 : Select only those that have null  number of rooms*/

select *
from tbl_family f
left join
tbl_verifier v
ON f.familyID = v.familyID
WHERE f.Members is null

现在我有点纠结于如何进一步操作。

使用
UNION All
合并两个结果集

    select *
    from tbl_family f
    inner join tbl_verifier v ON f.familyID = v.familyID
    and f.Members = v.Members 

    union all

    select * from tbl_family f
    left join tbl_verifier v ON f.familyID = v.familyID and and f.Members = v.Members
    where v.familyID is null

使用
UNION All
合并两个结果集

    select *
    from tbl_family f
    inner join tbl_verifier v ON f.familyID = v.familyID
    and f.Members = v.Members 

    union all

    select * from tbl_family f
    left join tbl_verifier v ON f.familyID = v.familyID and and f.Members = v.Members
    where v.familyID is null

听起来怎么样?我认为它有效

SELECT f.*
FROM tbl_family f, tbl_verifier v
WHERE (f.familyID = v.familyID AND f.Members = v.Members)
      OR f.familyID NOT IN (SELECT familyID FROM tbl_verifier)

听起来怎么样?我认为它有效

SELECT f.*
FROM tbl_family f, tbl_verifier v
WHERE (f.familyID = v.familyID AND f.Members = v.Members)
      OR f.familyID NOT IN (SELECT familyID FROM tbl_verifier)

对您的情况使用UNION ALL,但最好为相同的情况添加位置过滤器

; with cte as (
    select tbl_family.family_id, tbl_family.Members, tbl_family.location
    from tbl_family 
    inner join tbl_verifier ON tbl_family.familyID = tbl_verifier.familyID
    and tbl_family.Members = tbl_verifier.Members and tbl_family.Location = tbl_verifier.Location 
    union all
    select tbl_family.family_id, tbl_family.Members, tbl_family.location
    from tbl_family 
    left join tbl_verifier ON tbl_family.familyID = tbl_verifier.familyID 
    where tbl_family.Members is null
)
Select * from cte order by family_id

对您的情况使用UNION ALL,但最好为相同的情况添加位置过滤器

; with cte as (
    select tbl_family.family_id, tbl_family.Members, tbl_family.location
    from tbl_family 
    inner join tbl_verifier ON tbl_family.familyID = tbl_verifier.familyID
    and tbl_family.Members = tbl_verifier.Members and tbl_family.Location = tbl_verifier.Location 
    union all
    select tbl_family.family_id, tbl_family.Members, tbl_family.location
    from tbl_family 
    left join tbl_verifier ON tbl_family.familyID = tbl_verifier.familyID 
    where tbl_family.Members is null
)
Select * from cte order by family_id

UNION ALL
似乎是一个合理的解决方案。最大的问题是,如果有多行,如何从第一个表中取出一行

下面是一个使用
MAX()
的方法:


您的问题不清楚家庭是否可以位于多个位置。如果是这样,您需要在correlation子句中包含
location

UNION ALL
似乎是一个合理的解决方案。最大的问题是,如果有多行,如何从第一个表中取出一行

下面是一个使用
MAX()
的方法:


您的问题不清楚家庭是否可以位于多个位置。如果是这样的话,你需要在相关子句中包含
位置

从上面发布的不同答案中,我能够想出以下脚本,它很有效

 ; with cte as (select f.familyID,
  f.Members,
  f.Location
  from tbl_family f
  inner join tbl_verifier v ON f.familyID = v.familyID
  and f.Members = v.Members 

  union all

  select f.familyID,
  f.Members,
  f.Location from tbl_family f
  left join tbl_verifier v ON f.familyID = v.familyID 
  where f.Members is NULL
)
SELECT * INTO temp1 FROM cte

SELECT * FROM tbl_family WHERE familyID NOT IN (SELECT familyID FROM temp1)
UNION ALL 
SELECT * FROM temp1
ORDER BY familyID

从上面贴出的不同答案中,我想出了下面的脚本

 ; with cte as (select f.familyID,
  f.Members,
  f.Location
  from tbl_family f
  inner join tbl_verifier v ON f.familyID = v.familyID
  and f.Members = v.Members 

  union all

  select f.familyID,
  f.Members,
  f.Location from tbl_family f
  left join tbl_verifier v ON f.familyID = v.familyID 
  where f.Members is NULL
)
SELECT * INTO temp1 FROM cte

SELECT * FROM tbl_family WHERE familyID NOT IN (SELECT familyID FROM temp1)
UNION ALL 
SELECT * FROM temp1
ORDER BY familyID

今天的提示:始终使用现代、明确的
JOIN
语法。更易于编写(无错误),更易于读取(和维护),并且在需要时更易于转换为外部联接。这仍然是今天的重复提示:始终使用现代的显式
联接
语法。更容易写入(无错误)、更容易读取(和维护),并且在需要时更容易转换为外部联接。这仍然返回重复项是否可能tbl_验证程序中存在familyID,但tbl_族中不存在?不同的地点呢?tbl_验证器可以有familyID副本吗?标题中提到的MySQL,或者(Microsoft)标记的SQL Server?!?!?!?!这里的主要问题是以一种奇怪的方式存储数据。解决了这个问题,您就不会有这个问题。@jahlh familyID存在于这两个表中是否可能存在一个familyID存在于tbl_验证器中而不存在于tbl_族中?不同的地点呢?tbl_验证器可以有familyID副本吗?标题中提到的MySQL,或者(Microsoft)标记的SQL Server?!?!?!?!这里的主要问题是以一种奇怪的方式存储数据。解决了这个问题,您就不会有这个问题了。@jahlh familyID在两个表中都存在这只返回2行。对于没有重复项的familyID 100和101,这仅返回2行。对于没有副本的familyID 100和101,这只返回两行;对于家庭ID 100和101。我需要102和103也包括在内102仍然没有被返回这只是返回两行;对于家庭ID 100和101。我需要102和103被包括在内102仍然没有被返回