繁体   English   中英

获取不同的代号对,但在其他列上排序

[英]Getting a distinct code-name pair but sorting on other columns

我在编写查询时有些困惑(SQL不是我的强项)。

说我有以下TABLE1

CODE NAME     SCOPE1  SCOPE2    SEQ
------------------------------------
A    a        Here              1
B    b        Here              2
C    c        Here              3
C    c                Room      1
A    aa               Room      2
B    bbb              Room      3

业务密钥是CODE + SCOPE1 + SCOPE2 ,其中SCOPE1SCOPE2始终是互斥的。

鉴于我需要按SCOPE1SCOPE2SEQ排序,如何得到CODENAME的不同结果?

也就是说,给定SCOPE1 = 'Here'SCOPE2 = 'Room' ,我想得到以下结果:

CODE NAME
---------
A    a
B    b
C    c
A    aa
B    bbb

注意:不需要Room C c ,因为它与Here C c重复。

我确实意识到将DISTINCTORDER BY结合使用的局限性,我能想到的最好的方法如下:

select distinct CODE, NAME from
(
    select CODE, NAME from MYTABLE
    where (SCOPE1='Here' or SCOPE2='Room')
    order by SCOPE1, SCOPE2, SEQ
);

上面产生正确的对,但顺序错误。 我尝试弄乱GROUP BY ,但我想我还不够了解。

我必须坚持使用标准SQL(也就是说,没有产品专用的SQL构造,除非是Oracle,否则),并且我猜想使用此特定查询可能无法避免子选择。

我将不胜感激任何指针。 提前致谢。

更新:我已经更新了数据集,根据peterm的回答,到目前为止,这是我所拥有的: sqlfiddle 当我开始调整序列时,MIN / MAX技巧不起作用。

假定我将始终搜索一个特定的SCOPE1与一个特定的SCOPE2配对。 但是我需要所有SCOPE1记录都出现在SCOPE2之前。 这个想法是,我不在乎是否CODE + NAME来自SCOPE1SCOPE2 -我只是想唯一对由分类SCOPE1SCOPE2SEQ

更新基于您对Oracle的更新要求

SELECT CODE, NAME
  FROM
(
  SELECT CODE, NAME, 
         ROW_NUMBER() OVER (ORDER BY SCOPE1, SCOPE2, SEQ) rnum
    FROM Table1
   WHERE SCOPE1='Here' 
      OR SCOPE2='Room'
) q 
 GROUP BY CODE, NAME
 ORDER BY MIN(rnum)

这是SQLFiddle

使它在SQL Server中以相同的方式工作

SELECT CODE, NAME
  FROM
(
  SELECT CODE, NAME, 
         ROW_NUMBER() OVER (ORDER BY CASE WHEN SCOPE1 IS NULL 
                                          THEN 1 ELSE 0 END, SCOPE1,
                                     CASE WHEN SCOPE2 IS NULL 
                                          THEN 2 ELSE 3 END, SCOPE2, SEQ) rnum
    FROM Table1
   WHERE SCOPE1='Here' 
      OR SCOPE2='Room'
) q 
 GROUP BY CODE, NAME
 ORDER BY MIN(rnum)

这是SQLFiddle

输出:

| CODE | NAME |
---------------
|    A |    a |
|    B |    b |
|    C |    c |
|    A |   aa |
|    B |  bbb |

原始答案:根据您对需求的描述,我唯一想到的就是

SELECT CODE, NAME
  FROM Table1
 WHERE SCOPE1='Here' 
    OR SCOPE2='Room'
 GROUP BY CODE, NAME
 ORDER BY MIN(SCOPE1), MIN(SCOPE2), MIN(SEQ)

这是SQLFiddle演示(MySql)
这是SQLFiddle演示(SQL Server)
这是SQLFiddle演示(Oracle)

现在在MySql和SQL Server中,默认情况下首先使用NULL ,因此您将获得

| CODE | NAME |
---------------
|    B |  bbb |
|    A |    a |
|    B |    b |
|    C |    c |

在Oracle NULL ,默认情况下走最后一个,因此您将获得

| CODE | NAME |
---------------
|    A |    a |
|    B |    b |
|    C |    c |
|    B |  bbb |

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM