I'm a bit stumped on writing a query (SQL not my strong point).
Say I have the following 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.
How can I get a distinct result of CODE
and NAME
given that I need sort by SCOPE1
, SCOPE2
, and SEQ
?
That is, given SCOPE1 = 'Here'
and SCOPE2 = 'Room'
, I would like to get this result:
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
.
I do realise the limitation of using DISTINCT
with ORDER BY
and the best I could come up with was the following:
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.
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.
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 . The MIN/MAX trick doesn't work well when I start tweaking the sequences.
The assumption is that I will always search for one specific SCOPE1
paired with one specific SCOPE2
. But I need all SCOPE1
records to appear before 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
.
UPDATE Based on your updated requirements for 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
To make it work the same way in 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
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)
Here is SQLFiddle demo (SQL Server)
Here is SQLFiddle demo (Oracle)
Now in MySql and SQL Server NULL
s go first by default therefore you'll get
| CODE | NAME | --------------- | B | bbb | | A | a | | B | b | | C | c |
In Oracle NULL
s go last by default therefore you'll get
| CODE | NAME | --------------- | A | a | | B | b | | C | c | | B | bbb |
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.