简体   繁体   English

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

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

I'm a bit stumped on writing a query (SQL not my strong point). 我在编写查询时有些困惑(SQL不是我的强项)。

Say I have the following TABLE1 : 说我有以下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

The business key is CODE + SCOPE1 + SCOPE2 , where SCOPE1 and SCOPE2 are always mutually exclusive. 业务密钥是CODE + SCOPE1 + SCOPE2 ,其中SCOPE1SCOPE2始终是互斥的。

How can I get a distinct result of CODE and NAME given that I need sort by SCOPE1 , SCOPE2 , and SEQ ? 鉴于我需要按SCOPE1SCOPE2SEQ排序,如何得到CODENAME的不同结果?

That is, given SCOPE1 = 'Here' and SCOPE2 = 'Room' , I would like to get this result: 也就是说,给定SCOPE1 = 'Here'SCOPE2 = 'Room' ,我想得到以下结果:

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

Note: C c from Room is not wanted as it's a duplicate to C c from Here . 注意:不需要Room C c ,因为它与Here C c重复。

I do realise the limitation of using DISTINCT with ORDER BY and the best I could come up with was the following: 我确实意识到将DISTINCTORDER BY结合使用的局限性,我能想到的最好的方法如下:

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

The above produces the correct pairs but in the wrong sequence. 上面产生正确的对,但顺序错误。 I tried messing around with GROUP BY , but I guess I didn't know enough. 我尝试弄乱GROUP BY ,但我想我还不够了解。

I have to stick with standard SQL (that is, no product-specific SQL constructs, unless it's Oracle, maybe), and I guess with this particular query, it's probably impossible to avoid subselects. 我必须坚持使用标准SQL(也就是说,没有产品专用的SQL构造,除非是Oracle,否则),并且我猜想使用此特定查询可能无法避免子选择。

I would be very grateful for any pointers. 我将不胜感激任何指针。 Thanks in advance. 提前致谢。

UPDATE: I've updated the data set, and based on peterm's answer, here's what I have so far: sqlfiddle . 更新:我已经更新了数据集,根据peterm的回答,到目前为止,这是我所拥有的: sqlfiddle The MIN/MAX trick doesn't work well when I start tweaking the sequences. 当我开始调整序列时,MIN / MAX技巧不起作用。

The assumption is that I will always search for one specific SCOPE1 paired with one specific SCOPE2 . 假定我将始终搜索一个特定的SCOPE1与一个特定的SCOPE2配对。 But I need all SCOPE1 records to appear before SCOPE2 . 但是我需要所有SCOPE1记录都出现在SCOPE2之前。 The idea is that I don't care whether CODE + NAME comes from SCOPE1 or SCOPE2 - I just want unique pairs that are sorted by SCOPE1 , SCOPE2 , and SEQ . 这个想法是,我不在乎是否CODE + NAME来自SCOPE1SCOPE2 -我只是想唯一对由分类SCOPE1SCOPE2SEQ

UPDATE Based on your updated requirements for Oracle 更新基于您对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)

Here is SQLFiddle 这是SQLFiddle

To make it work the same way in SQL Server 使它在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)

Here is SQLFiddle 这是SQLFiddle

Output: 输出:

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

Original answer: The only thing I could think of based on your description of requirements 原始答案:根据您对需求的描述,我唯一想到的就是

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

Here is SQLFiddle demo (MySql) 这是SQLFiddle演示(MySql)
Here is SQLFiddle demo (SQL Server) 这是SQLFiddle演示(SQL Server)
Here is SQLFiddle demo (Oracle) 这是SQLFiddle演示(Oracle)

Now in MySql and SQL Server NULL s go first by default therefore you'll get 现在在MySql和SQL Server中,默认情况下首先使用NULL ,因此您将获得

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

In Oracle NULL s go last by default therefore you'll get 在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