Self Join 或 EXISTS 在这里有帮助吗?
Does a Self Join or EXISTS Help here?
我正在使用 Advantage Server 12。
我需要一个结果集,当提供的参数出现在主数据或详细信息中时 table 当提供的值不是链接字段时查找所有记录。
客户Table
|AccountCode |Tel1|Tel2|Tel3|Accout Name/Address etc....
| ACODE | | | |
N < 2
联系Table
|AccountCode |cTel1|cTel2|cTel3|ContactName/Address etc....
| ACODE | | | |
N >=0
需要来自客户的行和来自联系人的 所有 具有匹配 ACODE 的行。
当提供 Tel1 或 Tel2 或 Tel3 或 cTel1 或 cTel2 或 cTel3 时
当在任何客户字段中找到提供的值 ('thenumber') 时,此 SQL 给出所需的结果
当在联系人 table 中找到提供的号码时,它 returns 客户字段和联系人
中匹配行的唯一数据
declare @Tel string;
set @Tel = 'thenumber';
select
@TEL as calling,c.Tel1,c.Tel2,c.contact as "Primary",
c.acnt_nmbr,c.Acnt_name, a.contact,a.cTel1 as telephone1,a.cTel2 as telephone2
from
customer c
full outer join contact a on (c.acnt_nmbr=a.acnt_nmbr)
where
replace(c.Tel1,' ','') = @Tel
or
replace(c.Tel2,' ','') = @Tel
or
replace(c.Tel3,' ','') = @Tel
or
replace(a.cTel1,' ','') = @Tel
or
replace(a.cTel2,' ','') = @Tel
or
replace(a.cTel3,' ','') = @Tel
在客户中找到 'thenumber' 时的结果 - 这就是我们想要的
calling Tel1 Tel2 Primary acnt_nmbr Acnt_name contact telephone1 telephone2
thenumber 11111111 thenumber KIERAN 687 theCo Pat 12234560 333444555
thenumber 11111111 thenumber KIERAN 687 theco Mary 45678900 444555666
thenumber 11111111 thenumber KIERAN 687 theco Jon 22233344
thenumber 11111111 thenumber KIERAN 687 theco Paul 22244455 124578111
thenumber 11111111 thenumber KIERAN 687 theco Jane 33225544
在联系人中找到 'thenumber' 时的结果 - 我们需要与上面相同的结果集
calling Tel1 Tel2 Primary acnt_nmbr Acnt_name contact telephone1 telephone2
thenumber 11111111 2222222 KIERAN 687 theco Jane thenumber
我在想一些自连接或 EXISTS 语句是答案,但不确定如何继续。
这比您预期的要棘手一些,就我刚刚看到您的最新评论而言,我希望我向您提出的解决方案能够奏效(我根本不了解 SAP 技术环境)。
就你的SQL点,我的处理方法如下。
对于客户和联系人,找到匹配的值。这对客户来说很容易,但对于联系人,您需要识别单个匹配值,然后在所有值都匹配的地方保留联系人
然后,构建客户和联系人的集合。
最后,合并来自两个第一个过滤器的结果,与基础数据相结合。
这是我提出的最终要求:
with cust_check as (
SELECT account_code, tel1, tel2, tel3, address,
CASE WHEN tel1 = @Tel THEN 1
ELSE CASE WHEN tel2 = @Tel THEN 1
ELSE CASE WHEN tel3 = @Tel THEN 1
ELSE 0
END
END
END as cust_match
from customer
),
cust_filter as (
SELECT account_code, tel1, tel2, tel3, address AS detail
FROM cust_check
WHERE cust_match = 1
),
contact_check as (
SELECT account_code, ctel1, ctel2, ctel3, cname,
CASE WHEN ctel1 = @Tel THEN 1
ELSE CASE WHEN ctel2 = @Tel THEN 1
ELSE CASE WHEN ctel3 = @Tel THEN 1
ELSE 0
END
END
END as contact_match
FROM contact
),
contact_filter as (
SELECT account_code, count(*) as nb_rows, sum(contact_match) as nb_matched
FROM contact_check
GROUP BY account_code
HAVING count(*) = sum(contact_match)
),
all_contacts as (
SELECT t.account_code, ctel1, ctel2, ctel3, cname, address
FROM contact as t
JOIN customer as c ON c.account_code = t.account_code
),
union_match as
(
SELECT c.account_code, c.ctel1, c.ctel2, c.ctel3, c.cname, c.address
FROM all_contacts c
JOIN cust_filter f ON f.account_code = c.account_code
UNION
SELECT c.account_code, c.ctel1, c.ctel2, c.ctel3, c.cname, c.address
FROM all_contacts c
JOIN contact_filter f ON f.account_code = c.account_code
)
SELECT account_code, ctel1, ctel2, ctel3, cname, address
FROM union_match
此请求基于 MS SQL 服务器,由于 DB-Fiddle,您可以轻松地 'play' 使用它 - 我只希望它符合您的限制!
这应该可以达到你想要的效果:
select
@TEL as calling,c.Tel1,c.Tel2,c.contact as "Primary",
c.acnt_nmbr,c.Acnt_name, a.contact,a.cTel1 as telephone1,a.cTel2 as telephone2
from
customer c
left join contact a on (c.acnt_nmbr=a.acnt_nmbr)
WHERE c.acnt_nmbr IN
(
SELECT DISTINCT acnt_nmbr FROM
(SELECT acnt_nmbr, Tel1, Tel2
FROM Customer
UNION
SELECT acnt_nmbr, cTel1, cTel2
FROM Contact) x
WHERE
replace(x.Tel1,' ','') = @Tel
or
replace(x.Tel2,' ','') = @Tel
)
(我会留给你解决如何添加 Tel3 :)
请注意,我已将您的完整外部联接更改为简单的左联接,因为所提供的代码不适用于无客户联系人。
如果你真的需要全外连接,代码会变得有点复杂:
SELECT z.* FROM
( select @TEL as calling,c.Tel1,c.Tel2,c.contact as "Primary",
COALESCE(c.acnt_nmbr,a.acnt_nmbr) AS AccountNo,
c.Acnt_name, a.contact,a.cTel1 as telephone1,a.cTel2 as telephone2
from
Customer c
full outer join Contact a on (c.acnt_nmbr=a.acnt_nmbr)
) z
WHERE COALESCE(z.AccountNo,0) IN
(...)
我已修改 Christophe's DB-fiddle 以显示此功能。
请注意,完全外部联接的解决方案在 fiddle 中略有不同,以应对 Microsoft SQL 服务器与 Advantage 数据库服务器相比的不同行为。 (例如,对于 ADS DBF 表,整数字段中的 NULL 值在 UNION 中变为零)。
我正在使用 Advantage Server 12。 我需要一个结果集,当提供的参数出现在主数据或详细信息中时 table 当提供的值不是链接字段时查找所有记录。
客户Table
|AccountCode |Tel1|Tel2|Tel3|Accout Name/Address etc....
| ACODE | | | |
N < 2
联系Table
|AccountCode |cTel1|cTel2|cTel3|ContactName/Address etc....
| ACODE | | | |
N >=0
需要来自客户的行和来自联系人的 所有 具有匹配 ACODE 的行。 当提供 Tel1 或 Tel2 或 Tel3 或 cTel1 或 cTel2 或 cTel3 时
当在任何客户字段中找到提供的值 ('thenumber') 时,此 SQL 给出所需的结果 当在联系人 table 中找到提供的号码时,它 returns 客户字段和联系人
中匹配行的唯一数据declare @Tel string;
set @Tel = 'thenumber';
select
@TEL as calling,c.Tel1,c.Tel2,c.contact as "Primary",
c.acnt_nmbr,c.Acnt_name, a.contact,a.cTel1 as telephone1,a.cTel2 as telephone2
from
customer c
full outer join contact a on (c.acnt_nmbr=a.acnt_nmbr)
where
replace(c.Tel1,' ','') = @Tel
or
replace(c.Tel2,' ','') = @Tel
or
replace(c.Tel3,' ','') = @Tel
or
replace(a.cTel1,' ','') = @Tel
or
replace(a.cTel2,' ','') = @Tel
or
replace(a.cTel3,' ','') = @Tel
在客户中找到 'thenumber' 时的结果 - 这就是我们想要的
calling Tel1 Tel2 Primary acnt_nmbr Acnt_name contact telephone1 telephone2
thenumber 11111111 thenumber KIERAN 687 theCo Pat 12234560 333444555
thenumber 11111111 thenumber KIERAN 687 theco Mary 45678900 444555666
thenumber 11111111 thenumber KIERAN 687 theco Jon 22233344
thenumber 11111111 thenumber KIERAN 687 theco Paul 22244455 124578111
thenumber 11111111 thenumber KIERAN 687 theco Jane 33225544
在联系人中找到 'thenumber' 时的结果 - 我们需要与上面相同的结果集
calling Tel1 Tel2 Primary acnt_nmbr Acnt_name contact telephone1 telephone2
thenumber 11111111 2222222 KIERAN 687 theco Jane thenumber
我在想一些自连接或 EXISTS 语句是答案,但不确定如何继续。
这比您预期的要棘手一些,就我刚刚看到您的最新评论而言,我希望我向您提出的解决方案能够奏效(我根本不了解 SAP 技术环境)。
就你的SQL点,我的处理方法如下。
对于客户和联系人,找到匹配的值。这对客户来说很容易,但对于联系人,您需要识别单个匹配值,然后在所有值都匹配的地方保留联系人
然后,构建客户和联系人的集合。
最后,合并来自两个第一个过滤器的结果,与基础数据相结合。
这是我提出的最终要求:
with cust_check as (
SELECT account_code, tel1, tel2, tel3, address,
CASE WHEN tel1 = @Tel THEN 1
ELSE CASE WHEN tel2 = @Tel THEN 1
ELSE CASE WHEN tel3 = @Tel THEN 1
ELSE 0
END
END
END as cust_match
from customer
),
cust_filter as (
SELECT account_code, tel1, tel2, tel3, address AS detail
FROM cust_check
WHERE cust_match = 1
),
contact_check as (
SELECT account_code, ctel1, ctel2, ctel3, cname,
CASE WHEN ctel1 = @Tel THEN 1
ELSE CASE WHEN ctel2 = @Tel THEN 1
ELSE CASE WHEN ctel3 = @Tel THEN 1
ELSE 0
END
END
END as contact_match
FROM contact
),
contact_filter as (
SELECT account_code, count(*) as nb_rows, sum(contact_match) as nb_matched
FROM contact_check
GROUP BY account_code
HAVING count(*) = sum(contact_match)
),
all_contacts as (
SELECT t.account_code, ctel1, ctel2, ctel3, cname, address
FROM contact as t
JOIN customer as c ON c.account_code = t.account_code
),
union_match as
(
SELECT c.account_code, c.ctel1, c.ctel2, c.ctel3, c.cname, c.address
FROM all_contacts c
JOIN cust_filter f ON f.account_code = c.account_code
UNION
SELECT c.account_code, c.ctel1, c.ctel2, c.ctel3, c.cname, c.address
FROM all_contacts c
JOIN contact_filter f ON f.account_code = c.account_code
)
SELECT account_code, ctel1, ctel2, ctel3, cname, address
FROM union_match
此请求基于 MS SQL 服务器,由于 DB-Fiddle,您可以轻松地 'play' 使用它 - 我只希望它符合您的限制!
这应该可以达到你想要的效果:
select
@TEL as calling,c.Tel1,c.Tel2,c.contact as "Primary",
c.acnt_nmbr,c.Acnt_name, a.contact,a.cTel1 as telephone1,a.cTel2 as telephone2
from
customer c
left join contact a on (c.acnt_nmbr=a.acnt_nmbr)
WHERE c.acnt_nmbr IN
(
SELECT DISTINCT acnt_nmbr FROM
(SELECT acnt_nmbr, Tel1, Tel2
FROM Customer
UNION
SELECT acnt_nmbr, cTel1, cTel2
FROM Contact) x
WHERE
replace(x.Tel1,' ','') = @Tel
or
replace(x.Tel2,' ','') = @Tel
)
(我会留给你解决如何添加 Tel3 :)
请注意,我已将您的完整外部联接更改为简单的左联接,因为所提供的代码不适用于无客户联系人。
如果你真的需要全外连接,代码会变得有点复杂:
SELECT z.* FROM
( select @TEL as calling,c.Tel1,c.Tel2,c.contact as "Primary",
COALESCE(c.acnt_nmbr,a.acnt_nmbr) AS AccountNo,
c.Acnt_name, a.contact,a.cTel1 as telephone1,a.cTel2 as telephone2
from
Customer c
full outer join Contact a on (c.acnt_nmbr=a.acnt_nmbr)
) z
WHERE COALESCE(z.AccountNo,0) IN
(...)
我已修改 Christophe's DB-fiddle 以显示此功能。
请注意,完全外部联接的解决方案在 fiddle 中略有不同,以应对 Microsoft SQL 服务器与 Advantage 数据库服务器相比的不同行为。 (例如,对于 ADS DBF 表,整数字段中的 NULL 值在 UNION 中变为零)。