我有四张桌子:
T1
ID ID1 TITLE
1 100 TITLE1
2 100 TITLE2
3 100 TITLE3
T2
ID TEXT
1 LONG1
2 LONG2
T3
ID1 ID2
100 200
T4
ID4 ID2 SUBJECT
1 200 A
2 200 B
3 200 C
4 200 D
5 200 E
我希望以这种结果格式输出:
TITLE TEXT SUBJECT
TITLE1 LONG1 A
TITLE2 LONG2 B
TITLE3 null C
null null D
null null E
所以我做了这个查询,但它给了我比它应有的更多的结果。示例标题asre显示的次数多于一次等。
SELECT
t1.title,
t2.text,
t4.subject
FROM t1
LEFT OUTER JOIN t2 ON t1.id=t2.id
INNER JOIN t3 ON t1.id1=t3.id1
LEFT OUTER JOIN t4 ON t4.id2=t3.id2
WHERE
t1.id1=100
感谢您的帮助
答案 0 :(得分:1)
免责声明:我不使用DB2。在浏览了一些文档后,我发现DB2支持row_number()和full outer join,但我可能很容易出错。
要摆脱n:m关系,必须建立额外的密钥。在这种情况下,简单的解决方案是在t1和t4中为每个记录添加行号,并将其用作连接条件。 Row_number就是这样,按照partition by
定义的顺序按升序生成由order by
定义的数据组的数字。
由于t1和t4中的记录数存在差异,并且不知道哪个记录总是有更多记录,我使用全外连接来加入它们。
您可以看到the test (Sql Server version) @ Sql Fiddle。
select t1_rn.title,
t2.[text],
t4_rn.subject
from
(
select t1.id,
t1.title,
t1.id1,
t3.id2,
row_number() over(partition by t1.id1
order by id) rn
from t1
inner join t3
on t1.id1 = t3.id1
) t1_rn
full outer join
(
select t4.subject,
t3.id1,
t4.id2,
row_number() over(partition by t4.id2
order by id4) rn
from t4
inner join t3
on t4.id2 = t3.id2
) t4_rn
on t1_rn.id1 = t4_rn.id1
and t1_rn.id2 = t4_rn.id2
and t1_rn.rn = t4_rn.rn
left join t2
on t1_rn.id = t2.id
这种工作绝对应该在应用程序的表示方面完成,但我相信您使用的软件需要已准备好的数据。
答案 1 :(得分:0)
试试这个:
select t1.title,t2.text,t4.subject
from t4
left join t3
on t4.id2=t3.id2
left join t1
on t1.id1=t3.id1
left join t2
on t1.id=t2.id
where t1.id=100
答案 2 :(得分:0)
你应该改变你的表格。您的上次联接会对您的输出执行此操作 - 只需分析您的查询。对于T1的每一条记录,你都有来自T4的每条记录。
答案 3 :(得分:0)
外部联接保证复制行,而不是仅匹配您需要的行。你可能想看看这个: http://blog.sqlauthority.com/2009/04/13/sql-server-introduction-to-joins-basic-of-joins/
了解联接类型是什么,以及如何使用它们。
您正在寻找具有相关文字和标题的主题列表,但这可能不是唯一的;每个标题都存在多个空值。您希望从表4中驱动联接,并获取主题列表,并为每个主题添加相关标题。
答案 4 :(得分:0)
查看您的输出,您似乎希望显示所有主题。知道了这一点,你应该首先在这张桌子上建造所有东西。
SELECT columns
FROM T4
接下来建立内部联接。
SELECT columns
FROM T4 subjectTable
INNER JOIN T3 mapTable
ON mapTable.ID2 = subjectTable.ID2
如果对它们感到满意,请使用外部联接添加可选列。
SELECT columns
FROM T4 subjectTable
INNER JOIN T3 mapTable
ON mapTable.ID2 = subjectTable.ID2
LEFT OUTER JOIN T2 textTable
ON textTable.ID = subjectTable.ID4
LEFT OUTER JOIN T1 titleTable
ON titleTable.ID1 = mapTable.ID1
WHERE
subjectTable.ID = 100;