我正在寻找一种方法来获得3个表之间的差异。我不能做的主要任务是比较列表格a并取决于它包含什么,它与表b和c比较2柱。 一个例子将阐明我正在尝试做什么:
Table A:
IpAddress |HostName
10.10.01.10 | somethingtada
255.255.255.1| something.else
Table B:
IpAddress |HostName |Name
10.10.01.10 |somethingtada.tada |somethingtada
Table C:
IpAddress |HostName |Name
255.255.255.1| something.else |something
1.1.1.1 | blabla.tada |tada
我需要有一个表格,向我显示这样的数据
IpAddress |HostName |TableA|TableB|TableC
10.10.01.10 |somethingtada.tada|1 |1 |0
255.255.255.1|something.else |1 |0 |1
1.1.1.1 |blabla.tada |0 |0 |1
所以,如果它不够清楚,当我有一个“。”在TableA中的hostName列中(这种情况总是发生在tableA中)我将它与Hostname与其他表进行比较。但如果没有“。”在TableA的主机名中,我将它与另外2个表的列名进行比较。
我现在拥有的是:
select IPAddress, HostName,
SUM(case when tbl = 'a' then 1 else 0 end) TableB,
SUM(case when tbl = 'b' then 1 else 0 end) TableC,
SUM(case when tbl = 'c' then 1 else 0 end) TableA
from
(
select IPAdress, HostName,'a' tbl
from TableB
union all
select IPAdress, HostName,'b' tbl
from TableC
union all
select IPAdress, HostName,'c' tbl
from TableA
) d
group by IPAddress, HostName
它运作良好,但我不知道如何比较其他表取决于是否有“。”在表A中的主机名列中。
#EDIT1:
Table A:
IpAddress |HostName
10.10.01.10 | somethingtada
255.255.255.1| something.else
255.10.10.1 | bliblio
1.1.1.1 | tada
2.2.2.2 | tada3.tada
2.2.2.2 | tada5.tada
Table B:
IpAddress |HostName |Name
10.10.01.10 |somethingtada.tada |somethingtada
255.1.1.1 |test3.test |test3
126.126.126.1|test4.test |test4
2.2.2.2 |tada5.tada |tada5
Table C:
IpAddress |HostName |Name
255.255.255.1| something.else |something
1.1.1.1 | blabla.tada |blabla
255.1.1.1 | test3.test |test3
3.3.3.3 | test5.test |test5
我需要有一个表格,向我显示这样的数据
IpAddress |HostName |TableA|TableB|TableC
10.10.01.10 |somethingtada.tada|1 |1 |0
255.255.255.1|something.else |1 |0 |1
1.1.1.1 |blabla.tada |1 |0 |1
255.10.10.1 |blibio |1 |0 |0
255.1.1.1 |test3.test |0 |1 |1
126.126.126.1|test4.test |0 |1 |0
2.2.2.2 |tada3.tada |1 |0 |0
3.3.3.3 |test5.test |0 |0 |1
2.2.2.2 |tada5.tada |1 |1 |0
提前致谢
答案 0 :(得分:2)
这个怎么样
select
coalesce(a.ipaddress, b.ipaddress, c.ipaddress),
coalesce(b.hostname, c.hostname, a.hostname),
case when a.ipaddress is not null then 1 else 0 end,
case when b.ipaddress is not null then 1 else 0 end,
case when c.ipaddress is not null then 1 else 0 end
from
tablea a
full join tableb b on
a.ipaddress = b.ipaddress and (
(a.hostname like '%.%' and a.hostname = b.hostname) or
(a.hostname not like '%.%' and a.hostname = b.name)
)
full join tablec c on
a.ipaddress = c.ipaddress and (
(a.hostname like '%.%' and a.hostname = c.hostname) or
(a.hostname not like '%.%' and a.hostname = c.name)
)
编辑: Andriy M建议的改进对我来说听起来不错。这是完整的改进版本:
select
coalesce(a.ipaddress, b.ipaddress, c.ipaddress),
coalesce(b.hostname, c.hostname, a.hostname),
case when a.ipaddress is not null then 1 else 0 end,
case when b.ipaddress is not null then 1 else 0 end,
case when c.ipaddress is not null then 1 else 0 end
from
tablea a
full join tableb b on
a.ipaddress = b.ipaddress and (
(a.hostname like '%.%' and a.hostname = b.hostname) or
(a.hostname not like '%.%' and a.hostname = b.name)
)
full join tablec c on
coalesce(a.ipaddress, b.ipaddress) = c.ipaddress and (
(a.hostname like '%.%' and a.hostname = c.hostname) or
(a.hostname not like '%.%' and a.hostname = c.name) or
(a.hostname is null and b.hostname = c.hostname)
)
我没时间更新sqlfiddle并对其进行测试,但是如果你在更大的输入上运行它,你应该能够看到差异。我的原始查询无法正确连接TableA=0 TableB=1 TableC=1
的输出行,但应在更新的查询中修复它。
答案 1 :(得分:1)
您可以尝试更换此部分:
select AdresseIP, HostName,'c' tbl
from TableA
有这样的事情:
SELECT
IPAddress,
COALESCE(
CASE WHEN HostName NOT LIKE '%.%' THEN
(
SELECT TOP 1 HostName
FROM (
SELECT HostName
FROM TableB
WHERE IPAddress = TableA.IPAdress
AND Name = TableA.HostName
UNION ALL
SELECT HostName
FROM TableC
WHERE IPAddress = TableA.IPAdress
AND Name = TableA.HostName
) s
)
END,
HostName
) AS HostName,
'c' AS tbl
FROM TableA
它的工作原理如下。对于TableA
中的每一行,如果HostName
中没有.
(NOT LIKE '%.%'
),则查询会同时查找TableB
和{{1}对于TableC
,相应的HostName
和IPAddress
匹配当前Name
行的TableA
和IPAddress
。然后合并两个表的结果,并返回一个联合集的值,以替换当前行的HostName
。
如果当前行的HostName
本身具有HostName
,或者在其他两个表中找不到匹配的.
,则使用当前行HostName
本身而不是上述行。
为了澄清,这是在更换我在开头提到的部分之后整个查询的样子:
select IPAddress, HostName,
SUM(case when tbl = 'a' then 1 else 0 end) TableB,
SUM(case when tbl = 'b' then 1 else 0 end) TableC,
SUM(case when tbl = 'c' then 1 else 0 end) TableA
from
(
select AdresseIP, HostName,'a' tbl
from TableB
union all
select AdresseIP, HostName,'b' tbl
from TableC
union all
SELECT
IPAddress,
COALESCE(
CASE WHEN HostName NOT LIKE '%.%' THEN
(
SELECT TOP 1 HostName
FROM (
SELECT HostName
FROM TableB
WHERE IPAddress = TableA.IPAdress
AND Name = TableA.HostName
UNION ALL
SELECT HostName
FROM TableC
WHERE IPAddress = TableA.IPAdress
AND Name = TableA.HostName
) s
)
END,
HostName
) AS HostName,
'c' AS tbl
FROM TableA
) d
group by IPAddress, HostName
;
请不要屏住表演。但是,也许这会给你一些想法,你最终会找到一个更好的解决方案。