Sql 使用分组方式中表中的数据
名称:Sql 使用分组方式中表中的数据,sql,oracle,Sql,Oracle,名称: 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
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
家长:
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
预期产量
(没有“学生:”/“家长:”)
使用上述数据,我如何实现预期输出
我目前使用与此类似的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
我会在SQL中这样做:
Select last +', '+ first as fullname from names;
这篇评论太长了 你的问题没有道理。这个问题的简单答案是:
select last, first
from names;
但这似乎不太可能是你想要的
您的示例查询提到了一个表
术语
。这在问题的其他地方没有提到。请澄清问题或删除此问题并询问另一个问题。通用SQL,嗯,我希望有一个通用SQL:)
首先,您希望停止使用Oracle独有的仿古(+)联接语法
select b.last, b.first
from term a
LEFT OUTER JOIN names b ON a.id = b.id
order by b.last
这是更一般的方式!(注意:您可以缩写为just LEFT JOIN)
现在要连接(姓氏逗号空格名字),有一些选项不是通用的
SQL Server/MySQL和其他支持CONCAT()的服务器
并非所有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)
在这种形式中,如果还不是字符串类型,则必须显式地将数据类型强制转换为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
请看:我想我知道你想做什么了。我认为您可以设置一个派生表,然后查询它。设置如下内容:case when student id=id然后1或0作为匹配项或其他任何内容。然后查询派生表并按匹配分组。这种查询的思想是将数据分解为有助于解决问题的内容,然后根据需要将其重新组合在一起。在本例中,我将使用公共表表达式,它允许我将查询视为表,然后方便地重新组合它们 从期望的结果来看,我们似乎希望学生们先出现,然后是他们的母亲(女士优先:-),然后是他们的父亲。那么,好吧,让我们看看如何提取所需的数据。我们可以简单地获取学生及其相关数据:
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
列的常量值为零,仅用于标识这是一名学生。(你马上就会明白原因了)
现在,获取母亲的信息有点困难,因为我们没有任何性别信息可供使用。但是,我们将使用我们现有的名称。我们知道像梅尔文、米尔顿和乔丹这样的名字都是“男人”的名字。(是的,我知道Jordan也可以是女孩的名字。我女儿有一个叫Jordan的男教练,还有一个叫Jordan的女队友。就这么说吧——在这个例子中,Jordan是一个男孩的名字,'K?'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')
请注意,这里我们为母亲的type
列指定了值1
类似地,我们会找到父亲:
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
好的-鉴于上述情况,我们只需要正确组合数据。但是,我们不希望使用联接,因为我们希望名称从查询中一个接一个地吐出,而在SQL中,我们这样做的方式是使用UNION
或UNION ALL
操作符。(通常,您会希望使用UNION ALL
,因为UNION
将检查结果集,以确保没有重复的结果集-如果结果集很大,这或多或少会花费很长时间!)。因此,最终的查询如下所示:
with all_students as (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),
all_mothers as (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')),
all_fathers as (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'))
select last || ', ' || first as name from
(select * from all_students
union all
select * from all_mothers
union all
select * from all_fathers)
order by student_id desc, type;
我们只需要获取学生数据,然后是妈妈数据,然后是爸爸数据,然后按照学生ID从高到低排序(我只是查看了期望的结果,以确定这应该是一个降序排序),然后按照类型排序(结果是学生(type=0)排在第一位,然后是他们的妈妈(type=1)然后是他们的父亲(类型=2)
共享和享受。您使用的是
mySQL
还是Oracle
RDBMS?Oracle。但是我想知道任何SQL语法的一般逻辑,通常通过连接和得到一个稍微分解的表来解决这个问题,然后使用编程来格式化它。(您也可以在SQL中执行此操作,但它不是通用的)从名称p、名称s、家长中选择p.first、p.last、s.first.s.last,其中p.id=parents.id和s.id=parents.student_id按1,2,3,4排序。
with all_students as (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),
all_mothers as (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')),
all_fathers as (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'))
select last || ', ' || first as name from
(select * from all_students
union all
select * from all_mothers
union all
select * from all_fathers)
order by student_id desc, type;