我对SQL很陌生,并且正在努力查询(使用Access,FWIW)。我用Google搜索并搜索了StackOverflow,但我还没有看到这个确切的场景。 (这也可能是因为我不知道正确的搜索条件。)
我有两个非常简单的表,包含类似的数据。
table1: state, lname, fname, network
table2: state, lname, fname, network
我想要的是找到两个表中匹配的每个人/州组合以及该人所在的每个表中的网络:
state, lname, fname, t1.network, t2.network.
此人可能位于每个表格中的多个网络中。我希望看到该人所属的每个网络(来自两个表)。
我开始使用如下的JOIN:
SELECT t1.state, t1.lname, t1.fname, t1.network, t2.network
FROM t1 INNER JOIN t2
ON t1.fname=t2.fname AND t1.lname=t2.lname AND t1.state=t2.state
GROUP BY t1.state, t1.lname, t1.fname, t1.network, t2.network
我很快发现我得到了笛卡尔积。因此,如果“NY,Smith,John”在t1的两个网络和t2的三个网络中,我会得到这样的结果:
NY, Smith, John, NetworkA, NetworkB
NY, Smith, John, NetworkA, NetworkA
NY, Smith, John, NetworkB, NetworkA
NY, Smith, John, NetworkB, NetworkB
NY, Smith, John, NetworkA, NetworkC
NY, Smith, John, NetworkB, NetworkC
我真正想看到的只是:
NY, Smith, John, NetworkA, NetworkA
NY, Smith, John, NetworkB, NetworkB
NY, Smith, John, NULL, NetworkC
任何人都可以就如何继续或指出正确的方向给我一些建议吗?
答案 0 :(得分:1)
所以看起来你希望每个表中的所有记录都是相同的,然后只有每个记录中的记录都是不同的。这意味着您需要UNION 3组查询。
尝试这样的事情:
SELECT t1.state,
t1.lname,
t1.fname,
t1.network as t1Network,
t2.network as t2Network
FROM table1 t1
INNER JOIN table2 t2
ON t1.fname=t2.fname
AND t1.lname=t2.lname
AND t1.state=t2.state
AND t1.network=t2.network
UNION
SELECT t1.state,
t1.lname,
t1.fname,
t1.network as t1Network,
t2.network as t2Network
FROM table1 t1
LEFT JOIN table2 t2
ON t1.fname=t2.fname
AND t1.lname=t2.lname
AND t1.state=t2.state
AND t1.network=t2.network
WHERE t2.network IS NULL
UNION
SELECT t2.state,
t2.lname,
t2.fname,
t1.network as t1Network,
t2.network as t2Network
FROM table2 t2
LEFT JOIN table1 t1
ON t1.fname=t2.fname
AND t1.lname=t2.lname
AND t1.state=t2.state
AND t1.network=t2.network
WHERE t1.network IS NULL
这可以为您提供所需的结果。
以下是要确认的SQL Fiddle。
- 编辑
今天没想到 - 你真的不需要第一次查询。您可以从第二个查询中删除WHERE条件,它的工作方式相同。累了: - )
这是更新的查询 - 两者都应该可以正常工作,这更容易阅读:
SELECT t1.state,
t1.lname,
t1.fname,
t1.network as t1Network,
t2.network as t2Network
FROM table1 t1
LEFT JOIN table2 t2
ON t1.fname=t2.fname
AND t1.lname=t2.lname
AND t1.state=t2.state
AND t1.network=t2.network
UNION
SELECT t2.state,
t2.lname,
t2.fname,
t1.network as t1Network,
t2.network as t2Network
FROM table2 t2
LEFT JOIN table1 t1
ON t1.fname=t2.fname
AND t1.lname=t2.lname
AND t1.state=t2.state
AND t1.network=t2.network
WHERE t1.network IS NULL
顺便说一句 - 这些都应该在MSAccess中起作用,因为它支持UNION
。
答案 1 :(得分:0)
SELECT DISTINCT t1.state, t1.lname, t1.fname, t1.network, t2.network
FROM t1 INNER JOIN t2
ON t1.fname=t2.fname AND t1.lname=t2.lname AND t1.state=t2.state
GROUP BY t1.state, t1.lname, t1.fname, t1.network, t2.network
你得到了你想要的东西。
几乎每个联接都开始构建一个笛卡尔积(参见Inside SQL Server:查询书)。当您尝试过滤掉数据时,通常,创建的虚拟表将在您使用distinct时返回一个不同的集合。实际上,没有阻止笛卡尔积。
答案 2 :(得分:0)
在这种情况下,UNION应该是你最好的选择:
SELECT * FROM t1
UNION
SELECT * FROM t2
(请注意,如果两个表中的所有列的类型相同,顺序相同,则此查询应该按原样运行 - 否则最好指定每个必需的列,而不是使用SELECT *
)。
答案 3 :(得分:0)
你想要的是一个UNION。
我将创建一个查询(在SQL视图中),效果为:
SELECT state, lname, fname, network, network
FROM t1
UNION ALL
SELECT state, lname, fname, network, network
FROM t2
然后我会创建其他查询该查询的查询。
我自己尝试给你提供更多详细信息,但我没有安装MS Access。
答案 4 :(得分:0)
一种选择是使用完全外连接:
SELECT coalesce(t1.state, t2.state), coalesce(t1.lname, t2.lname), coalesce(t1.fname, t2.fname),
t1.network, t2.network
FROM t1 FULL OUTER JOIN t2
ON t1.fname=t2.fname AND t1.lname=t2.lname AND t1.state=t2.state
and t1.network = t2.network
输出:
NY SMITH JOHN A A
NY SMITH JOHN B B
NY SMITH JOHN NULL C
编辑:我没有看到你正在使用Access - 这是标准的SQL,但我不知道它是否会在那里工作。