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;