名:
id, first, last
879 Scotty Anderson
549 Melvin Anderson
554 Freddy Appleton
321 Grace Appleton
112 Milton Appleton
189 Jackson Black
99 Elizabeth Black
298 Jordan Frey
父母:
id, student_id
549 879
321 554
112 554
99 189
298 189
(没有'学生:' /'家长:')
Student: Anderson, Scotty
Parent: Anderson, Melvin
Student: Appleton, Freddy
Parent: Appleton, Grace
Parent: Appleton, Milton
Student: Black, Jackson
Parent: Black, Elizabeth
Parent: Frey, Jordan
使用上述数据,我如何实现预期的输出?
我目前使用与此类似的SQL来获取当前学生和姓名的列表。
select b.last, b.first
from term a, names b
where a.id = b.id(+)
order by b.last
返回:
Anderson, Scotty
Appleton, Freddy
Black, Jackson
我的问题是如何获取parents
表并添加到此查询以便它具有此输出:
Anderson, Scotty
Anderson, Melvin
Appleton, Freddy
Appleton, Grace
Appleton, Milton
Black, Jackson
Black, Elizabeth
Frey, Jordan
答案 0 :(得分:1)
泛型SQL,mmmmm我希望有一个通用SQL:)
首先,您要停止使用Oracle独有的古董(+)连接语法
select b.last, b.first
from term a
LEFT OUTER JOIN names b ON a.id = b.id
order by b.last
这是更通用的方式! (nb:你可以缩写为LEFT JOIN)
现在要连接(姓氏逗号空间名字),有些选项不是通用的
SQL Server / MySQL和其他支持CONCAT()
的人select CONCAT(b.last , ', ', b.first)
from term a
LEFT OUTER JOIN names b ON a.id = b.id
order by b.last
并非所有版本的Oracle或SQL Server都支持CONCAT() Oracle的concat()只需要2个参数; grrrrr
<强> ORACLE 强>
select b.last || ', ' || b.first
from term a
LEFT OUTER JOIN names b ON a.id = b.id
order by b.last
在这种形式下,Oracle通常会自动处理数据类型转换(我想,请检查日期/时间戳可能是其他人)
TSQL(Sybase,MS SQL Server)
select b.last + ', ' + b.first
from term a
LEFT OUTER JOIN names b ON a.id = b.id
order by b.last
在这种形式中,如果不是字符串类型,则必须显式地将数据类型转换/转换为n | var | char以进行连接
有关连接名称的列表:
除了姓氏之外,您还需要一种方法来将家庭群体保留在一起,并加上区分学生和家长。由于您只需要一列名称,这表明您需要一列指向姓氏和名字的id。因此,对表TERM
进行一些假设是你从中列出学生,然后追加与该组学生相关的父母,最后按所需顺序输出所需的列表。
select
case when type = 1 then 'Student' else 'Parent' end as who
, names.last || ', ' || names.first as Name
from (
select
STUDENT_ID as name_id
, STUDENT_ID as family_id
, 1 as TYPE
from term
union all
select
PARENTS.ID as name_id
, PARENTS.STUDENT_ID as family_id
, 2 as TYPE
from PARENTS
inner join term on PARENTS.STUDENT_ID = term.STUDENT_ID
) sq
inner join NAMES ON sq.name_id = NAMES.ID
order by
names.last
, sq.family_id
, sq.type
答案 1 :(得分:1)
这样的查询中的想法是将数据分解为可帮助您解决问题的内容,然后根据需要将其重新组合在一起。在这种情况下,我将使用公共表表达式,这允许我将查询视为表,然后轻松地重新组合它们。
看看期望的结果,看起来我们希望让学生先出现,然后是他们的母亲(女士们先:-),然后是他们的父亲。那么,好吧,让我们弄清楚如何提取所需的数据。我们可以非常简单地获得学生及其相关数据:
select distinct p.student_id as student_id,
n.first,
n.last,
0 as type
from parents p
inner join names n
on n.id = p.student_id
type
列的常量值为零,仅用于标识这是一名学生。 (你会在一分钟内看到原因)。
现在,由于我们没有任何性别信息可供使用,因此让母亲感到困难。但是,我们会使用我们拥有的名称。我们知道像Melvin,Milton和Jordan这样的名字是&#34; guy&#34;名。 (是的,我知道乔丹也可以成为一个女孩的名字。我的女儿有一个名叫乔丹的男教练,还有一个名叫乔丹的女队友。只要顺其自然 - 为了争论的目的,乔丹是个名字,&#39 ; K?&#39; K :-)。因此,我们会使用这些信息来帮助我们识别妈妈:
select p.student_id, n.first, n.last, 1 as type
from parents p
inner join names n
on n.id = p.id
where first not in ('Melvin', 'Milton', 'Jordan')
请注意,我们将值1分配给母亲的type
列。
同样,我们会找到爸爸:
select p.student_id, n.first, n.last, 2 as type
from parents p
inner join names n
on n.id = p.id
where first in ('Melvin', 'Milton', 'Jordan')
这里我们为类型指定值为2。
好的 - 鉴于上述情况,我们只需要正确组合数据。但是,我们不想使用JOIN,因为我们希望名称从查询中一个接一个地吐出 - 而我们在SQL中执行的方式是使用UNION
或{{ 1}}运算符。 (通常,您会想要使用UNION ALL
,因为UNION ALL
会检查结果集以确保没有重复项 - 在大型结果集需要的情况下,哦,或多或少FOREVER!)。因此,最终查询如下:
UNION
我们只取学生数据,然后是妈妈数据,然后是爸爸数据,然后根据学生ID从最高到最低排序(我只看了想要的结果,发现这应该是一个下降排序),然后按类型(导致学生(type = 0)成为第一,跟随他们的母亲(type = 1)然后他们的父亲(type = 2))。
分享并享受。
答案 2 :(得分:0)
我会在SQL中这样做:
Select last +', '+ first as fullname from names;
答案 3 :(得分:0)
评论太长了。
你的问题没有意义。问题的简单答案是:
select last, first
from names;
但似乎不太可能是你想要的。
您的示例查询提到了表term
。在问题的其他地方没有提到。请澄清问题或删除此问题并询问另一个问题。
答案 4 :(得分:0)
我想我明白了你要做的事情。我想你可以设置一个派生表然后查询它。设置如下:例如当学生id = id然后1其他0作为匹配或其他。然后按匹配查询派生表和分组。