SQL 联盟更喜欢来自一个 table 的记录?
SQL Union prefer records from one table?
我首先要说的是,我正在使用两个 table,它们的组织方式有点乱。我目前正在恳求我的案子对此进行调整,但无法控制它们。所以 tables 的组织是我无法控制的。
我有一个 table 看起来像这样
客户
| id | name | date_joined |
|----|------|-------------|
| 1 | Bob | 2012-01-01 |
| 2 | Jack | 2012-01-01 |
| 3 | Jill | 2012-01-01 |
自创建客户 table 以来,已创建另一个 table 来保存客户信息
客户 2
| id | name | year_joined | month_joined | day_joined |
|----|---------|-------------|--------------|------------|
| 4 | Ken | 2013 | 1 | 1 |
| 5 | Lindsey | 2013 | 1 | 1 |
| 1 | Bob | 2012 | 1 | 1 |
您会注意到,虽然 Customer2 包含前两个条目的新客户,但它也包含 Bob,他与第一个 table 中的鲍勃相同,并更新了信息以匹配新的 Customer2 table 布局。
我需要 select 基于 ID 列表将所有这些记录放入一个结果集中,假设 ID 是唯一的。因此我们可以确定 Customer 中的 Bob 与 Customer2 中的 Bob 相同。我目前正在用这样的联合声明来做这件事。
select *
from (
select id,
name,
date_joined,
'' as year_joined,
'' as month_joined,
'' as day_joined
from customer
union
select id,
name,
'' as date_joined,
year_joined,
month_joined,
day_joined
from customer2 )
as U where U.id in (list of ID's)
但是这会导致 table 看起来像这样
| id | name | date_joined | year_joined | month_joined | day_joined |
|----|---------|-------------|-------------|--------------|------------|
| 4 | Ken | | 2013 | 1 | 1 |
| 5 | Lindsey | | 2013 | 1 | 1 |
| 1 | Bob | | 2012 | 1 | 1 |
| 1 | Bob | 2012-01-01 | | | |
| 2 | Jack | 2012-01-01 | | | |
| 3 | Jill | 2012-01-01 | | | |
正如我们所见,我们有 Bob 的 'duplicate' 条记录,它们并不是真正的重复记录。我的问题是:当我遇到这样的 'duplicates' 时,有什么方法可以指定只从 Customer2 table 中选择记录吗?我需要这个,因为我不想重复,更愿意保留与最新 table 布局相匹配的记录。
您必须使数据完全匹配。像这样的东西可以工作:
select *
from (
select id,
name,
datepart(year,date_joined) as year_joined,
datepart(month,date_joined) as month_joined,
datepart(day,date_joined) as day_joined
from customer
union
select id,
name,
year_joined,
month_joined,
day_joined
from customer2 )
as U where U.id in (list of ID's)
这应该让你开始:
SELECT
id
, name
, date_joined
, NULL year_joined
, NULL month_joined
, NULL day_joined
FROM Customer
WHERE id NOT IN (SELECT id FROM Customer2)
UNION ALL
SELECT
id
, name
, NULL
, year_joined
, month_joined
, day_joined
FROM Customer2
ORDER BY id
;
或者,仅使用 SET 操作:
(SELECT
id
, name
, date_joined
, NULL year_joined
, NULL month_joined
, NULL day_joined
FROM Customer
EXCEPT
(SELECT
id
, name
, CONVERT(DATE,
CAST(year_joined AS VARCHAR(4)) + '-'
+ CAST(month_joined AS VARCHAR(2)) + '-'
+ CAST(day_joined AS VARCHAR(2))
, 102
)
, NULL
, NULL
, NULL
FROM Customer2
)
)
UNION ALL
SELECT
id
, name
, NULL
, year_joined
, month_joined
, day_joined
FROM Customer2
ORDER BY id
;
要么从 Customer 中获取 not 在 Customer2 中找到的那些,然后合并它们与所有在 Customer2:
中找到的
| id | name | date_joined | year_joined | month_joined | day_joined |
|----|---------|-------------|-------------|--------------|------------|
| 1 | Bob | (null) | 2012 | 1 | 1 |
| 2 | Jack | 2012-01-01 | (null) | (null) | (null) |
| 3 | Jill | 2012-01-01 | (null) | (null) | (null) |
| 4 | Ken | (null) | 2013 | 1 | 1 |
| 5 | Lindsey | (null) | 2013 | 1 | 1 |
查看实际效果:SQL Fiddle。
虽然我自己,我通常更喜欢真正的日期列而不是带有日期粒子的三列...
请评论,如果这需要调整/进一步的细节。
我首先要说的是,我正在使用两个 table,它们的组织方式有点乱。我目前正在恳求我的案子对此进行调整,但无法控制它们。所以 tables 的组织是我无法控制的。
我有一个 table 看起来像这样
客户
| id | name | date_joined |
|----|------|-------------|
| 1 | Bob | 2012-01-01 |
| 2 | Jack | 2012-01-01 |
| 3 | Jill | 2012-01-01 |
自创建客户 table 以来,已创建另一个 table 来保存客户信息
客户 2
| id | name | year_joined | month_joined | day_joined |
|----|---------|-------------|--------------|------------|
| 4 | Ken | 2013 | 1 | 1 |
| 5 | Lindsey | 2013 | 1 | 1 |
| 1 | Bob | 2012 | 1 | 1 |
您会注意到,虽然 Customer2 包含前两个条目的新客户,但它也包含 Bob,他与第一个 table 中的鲍勃相同,并更新了信息以匹配新的 Customer2 table 布局。
我需要 select 基于 ID 列表将所有这些记录放入一个结果集中,假设 ID 是唯一的。因此我们可以确定 Customer 中的 Bob 与 Customer2 中的 Bob 相同。我目前正在用这样的联合声明来做这件事。
select *
from (
select id,
name,
date_joined,
'' as year_joined,
'' as month_joined,
'' as day_joined
from customer
union
select id,
name,
'' as date_joined,
year_joined,
month_joined,
day_joined
from customer2 )
as U where U.id in (list of ID's)
但是这会导致 table 看起来像这样
| id | name | date_joined | year_joined | month_joined | day_joined |
|----|---------|-------------|-------------|--------------|------------|
| 4 | Ken | | 2013 | 1 | 1 |
| 5 | Lindsey | | 2013 | 1 | 1 |
| 1 | Bob | | 2012 | 1 | 1 |
| 1 | Bob | 2012-01-01 | | | |
| 2 | Jack | 2012-01-01 | | | |
| 3 | Jill | 2012-01-01 | | | |
正如我们所见,我们有 Bob 的 'duplicate' 条记录,它们并不是真正的重复记录。我的问题是:当我遇到这样的 'duplicates' 时,有什么方法可以指定只从 Customer2 table 中选择记录吗?我需要这个,因为我不想重复,更愿意保留与最新 table 布局相匹配的记录。
您必须使数据完全匹配。像这样的东西可以工作:
select *
from (
select id,
name,
datepart(year,date_joined) as year_joined,
datepart(month,date_joined) as month_joined,
datepart(day,date_joined) as day_joined
from customer
union
select id,
name,
year_joined,
month_joined,
day_joined
from customer2 )
as U where U.id in (list of ID's)
这应该让你开始:
SELECT
id
, name
, date_joined
, NULL year_joined
, NULL month_joined
, NULL day_joined
FROM Customer
WHERE id NOT IN (SELECT id FROM Customer2)
UNION ALL
SELECT
id
, name
, NULL
, year_joined
, month_joined
, day_joined
FROM Customer2
ORDER BY id
;
或者,仅使用 SET 操作:
(SELECT
id
, name
, date_joined
, NULL year_joined
, NULL month_joined
, NULL day_joined
FROM Customer
EXCEPT
(SELECT
id
, name
, CONVERT(DATE,
CAST(year_joined AS VARCHAR(4)) + '-'
+ CAST(month_joined AS VARCHAR(2)) + '-'
+ CAST(day_joined AS VARCHAR(2))
, 102
)
, NULL
, NULL
, NULL
FROM Customer2
)
)
UNION ALL
SELECT
id
, name
, NULL
, year_joined
, month_joined
, day_joined
FROM Customer2
ORDER BY id
;
要么从 Customer 中获取 not 在 Customer2 中找到的那些,然后合并它们与所有在 Customer2:
中找到的| id | name | date_joined | year_joined | month_joined | day_joined |
|----|---------|-------------|-------------|--------------|------------|
| 1 | Bob | (null) | 2012 | 1 | 1 |
| 2 | Jack | 2012-01-01 | (null) | (null) | (null) |
| 3 | Jill | 2012-01-01 | (null) | (null) | (null) |
| 4 | Ken | (null) | 2013 | 1 | 1 |
| 5 | Lindsey | (null) | 2013 | 1 | 1 |
查看实际效果:SQL Fiddle。
虽然我自己,我通常更喜欢真正的日期列而不是带有日期粒子的三列...
请评论,如果这需要调整/进一步的细节。