一个sql连接表的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个sql连接表的问题相关的知识,希望对你有一定的参考价值。

表A,B,C,D,实际四个表列数都不止这么多

表A
Id Name Age
1 name1 age1
2 name2 age2
4 name3 age3
7 name4 age4

表B
Id Comment Time
1 c1 t1
1 c2 t2
1 c3 t3
4 c4 t4
4 c5 t5
4 c6 t6
7 c7 t7

表C
Id Year Nick
1 y1 n1
7 y2 n2

表D
Id Used
7 1
7 0
7 0
7 1
7 0

把这四个表联起来,要求结果如下

ID Name Age Comment Time Year Nick Used
1 name1 age1 c1 t1 y1 n1 null
1 name1 age1 c2 t2 null null null
1 name1 age1 c3 t3 null null null
2 name2 age2 null null null null null
4 name3 age3 c4 t4 null null null
4 name3 age3 c5 t5 null null null
4 name3 age3 c6 t6 null null null
7 name4 age4 c7 t7 y2 n2 1
7 name4 age4 null null null null 0
7 name4 age4 null null null null 0
7 name4 age4 null null null null 1
7 name4 age4 null null null null 0
表A的id唯一,其他表的id不唯一,除了id其他字段不会重复。
结果中每个id所占的行数应该是B,C,D中含有该id最多的表的行数。

union的话,出来的结果冗余比较多,行数没要求的行数少。

可以换个思路 union 以后,合并行,
合并行的规则是,2行中的所有字段要么相同,要么至少一个为空,此时合并

由于表比较多,这个查询比较复杂。其实难点就在于,当同一个ID在两个表中的行数不相同时,怎样返回最大的行数,并且要求每行一一对应还不能重复。
以B表和C表为例。
首先,用row_number()函数分别为B表和C表生成一个辅助列seq(序号)。结果如下
Select *, row_number() over(partition by Id order by Comment, Time) as Seq from B
Id Comment Time Seq
1 c1 t1 1
1 c2 t2 2
1 c3 t3 3
4 c4 t4 1
4 c5 t5 2
4 c6 t6 3
7 c7 t7 1
-- Select *, row_number() over(partition by Id order by Year, Nick) as Seq from C
Id Year Nick Seq
1 y1 n1 1
7 y2 n2 1
接下来用Full Join连接这两个表。
select isnull(TB.Id TC.Id) as Id, Comment,Time,Year,Nick
from
(Select *, row_number() over(partition by Id order by Comment, Time) as Seq from B) as TB
FULL JOIN
(Select *, row_number() over(partition by Id order by Year, Nick) as Seq from C) as TC
on TB.Id = TC.Id and TB.Seq = TC.Seq
结果应该如下:
Id Comment Time Year Nick
1 c1 t1 y1 n1
1 c2 t2 null null
1 c3 t3 null null
4 c4 t4 null null
4 c5 t5 null null
4 c6 t6 null null
7 c7 t7 y2 n2
然后,用同样的方法将结果FULL JOIN 表D。
最后,表A LEFT JOIN 前几步的结果
参考技术A 表A INNER JOIN 表B
表A LEFT JOIN 表C
表A CROSS JOIN 表D
没测试,工参考追问

显然不对

参考技术B 你的表设计有问题,重新设计表结构,按你的设计,显示不出想要的结果追问

没问题我就不问了,我只是举个例子写的字段名,实际表的字段含义不是这样的。

参考技术C 还真搞不定 你这个厉害了。。。。。。
没法想要是 你能给出特定的数字兴许还能试试

Shell 脚本中的 SQL* PLUS 连接问题

【中文标题】Shell 脚本中的 SQL* PLUS 连接问题【英文标题】:Issue with the SQL* PLUS connections in a Shell Script 【发布时间】:2012-02-08 12:13:42 【问题描述】:

我们可以在一个 shell 脚本中有多个 SQL* PLUS 连接吗?

我编写了一个 shell 脚本,使用 SQL* PLUS 的 COPY 命令将表的数据从一个数据库复制到另一个数据库。我没有创建数据库链接的权限,所以我使用的是 COPY 命令。

我需要复制大约 50 个表的数据。当数据集较小时,它会运行并复制所有表的数据。但是当数据集很大时,它会卡住,我会在 unix 机器上收到会话不活动消息。

我想拆分语句并写如下:但是我收到错误“SP2-0042:未知命令“END1” - 其余行被忽略。”和 "SP2-0042: 未知命令 "END" - 忽略行的其余部分。"

#!/bin/bash
export ORACLE_HOME=/ora00/app/oracle/product/9.2.0.8
export PATH=$PATH:$ORACLE_HOME/bin

args=$#

if [ $args == 1 ]
then
    echo "Shell script started"
else
    echo "Wrong number of arguments"
exit 1  
fi

time_start=`date +%H%M%S`
echo $time_start

    sqlplus -s srcUN/srcPwd@srcSID <<END1       
    COPY from srcUN/srcPwd@srcSID to dstUN/dstPwd@dstSID INSERT tab1 USING SELECT * FROM tab1 WHERE col1 = $1;
    COPY from srcUN/srcPwd@srcSID to dstUN/dstPwd@dstSID INSERT tab2 USING SELECT * FROM tab2 WHERE col1 = $1;
    END1

    sqlplus -s srcUN/srcPwd@srcSID <<END2 
        COPY from srcUN/srcPwd@srcSID to dstUN/dstPwd@dstSID INSERT tab3 USING SELECT * FROM tab3 WHERE col1 = $1;
    END2

#END

你能帮我解决这个问题吗?

谢谢, 萨维塔

【问题讨论】:

你的问题的标题有点误导 - 这看起来像一个 shell 脚本问题。如果您更改标题,您可能会得到更多的 shell 脚本专家。 谢谢乔尔塔。我已经更改了标题...希望它现在可以使用。 :) 【参考方案1】:

问题在于END1END2 没有被识别为输入重定向的结尾,因为它们有前导空格。

删除这两行上的所有空格,它应该可以工作。

【讨论】:

以上是关于一个sql连接表的问题的主要内容,如果未能解决你的问题,请参考以下文章

连接表的 SQL 别名

SQL 查询 - 返回连接表的前两条记录的连接

是否可以获得 Hibernate sqlRestriction 的连接表的 SQL 别名?

sql查询:使用内连接查询两张表的时候,如果左边表的一条记录对应了右边表的两条记录,结果显示排列问题

SQL:具有相似表的多个左连接

跨三个表的 t-sql 外连接