Reputation: 2017
I have some table with users and table with codes. Every user has 4 codes. I need to return 4 codes for user with id 5234 but sorted alphabetically.
Like this:
SELECT
--results sorted alphabetically
<here_should_be 'aaa'> code1,
<here should be 'bbb'> code2,
<here should be 'ccc'> code3,
<here should be 'ddd'> code4
FROM
user bt
LEFT JOIN table_with_codes value_1 ON (bt.rk_id = value_1.rk_id AND value_1.code = 'code_1') --assume value_1.string_value return 'bbb'
LEFT JOIN table_with_codes value_2 ON (bt.rk_id = value_2.rk_id AND value_2.code = 'code_2') --assume value_2.string_value return 'aaa'
LEFT JOIN table_with_codes value_3 ON (bt.rk_id = value_3.rk_id AND value_3.code = 'code_3') --assume value_3.string_value return 'ddd'
LEFT JOIN table_with_codes value_4 ON (bt.rk_id = value_4.rk_id AND value_4.code = 'code_4') --assume value_4.string_value return 'ccc'
WHERE bt.id = 5234;
What is best way to do this?
Upvotes: 0
Views: 49
Reputation: 167982
Before the OP's update - if the 4 values are in different columns of the same row of the same table:
Oracle 11g R2 Schema Setup:
Query 1:
WITH data ( z1, z2, z3, z4 ) AS (
SELECT 'bbb', 'aaa', 'ccc', 'ddd' FROM DUAL
)
SELECT LEAST( z1, z2, z3, z4 ) c1,
CASE WHEN z1 <= z2 AND z2 <= z3 AND z2 <= z4 THEN z2
WHEN z1 <= z3 AND z3 <= z2 AND z3 <= z4 THEN z3
WHEN z1 <= z4 AND z4 <= z2 AND z4 <= z3 THEN z4
WHEN z2 <= z1 AND z1 <= z3 AND z1 <= z4 THEN z1
WHEN z2 <= z3 AND z3 <= z1 AND z3 <= z4 THEN z3
WHEN z2 <= z4 AND z4 <= z1 AND z4 <= z3 THEN z4
WHEN z3 <= z1 AND z1 <= z2 AND z1 <= z4 THEN z1
WHEN z3 <= z2 AND z2 <= z1 AND z2 <= z4 THEN z2
WHEN z3 <= z4 AND z4 <= z1 AND z4 <= z2 THEN z4
WHEN z4 <= z1 AND z1 <= z3 AND z1 <= z4 THEN z1
WHEN z4 <= z2 AND z2 <= z1 AND z2 <= z3 THEN z2
WHEN z4 <= z3 AND z3 <= z1 AND z3 <= z2 THEN z3 END AS c2,
CASE WHEN z1 >= z2 AND z2 >= z3 AND z2 >= z4 THEN z2
WHEN z1 >= z3 AND z3 >= z2 AND z3 >= z4 THEN z3
WHEN z1 >= z4 AND z4 >= z2 AND z4 >= z3 THEN z4
WHEN z2 >= z1 AND z1 >= z3 AND z1 >= z4 THEN z1
WHEN z2 >= z3 AND z3 >= z1 AND z3 >= z4 THEN z3
WHEN z2 >= z4 AND z4 >= z1 AND z4 >= z3 THEN z4
WHEN z3 >= z1 AND z1 >= z2 AND z1 >= z4 THEN z1
WHEN z3 >= z2 AND z2 >= z1 AND z2 >= z4 THEN z2
WHEN z3 >= z4 AND z4 >= z1 AND z4 >= z2 THEN z4
WHEN z4 >= z1 AND z1 >= z3 AND z1 >= z4 THEN z1
WHEN z4 >= z2 AND z2 >= z1 AND z2 >= z3 THEN z2
WHEN z4 >= z3 AND z3 >= z1 AND z3 >= z2 THEN z3 END AS c3,
GREATEST( z1, z2, z3, z4 ) c4
FROM data
| C1 | C2 | C3 | C4 |
|-----|-----|-----|-----|
| aaa | bbb | ccc | ddd |
After the OP's update - if the 4 values are in different rows of the same table:
Oracle 11g R2 Schema Setup:
CREATE TABLE users ( id, rk_id ) AS
SELECT 5234, 1 FROM DUAL;
CREATE TABLE table_with_codes (rk_id, code, string_value ) AS
SELECT 1, 'code1', 'bbb' FROM DUAL
UNION ALL SELECT 1, 'code2', 'ddd' FROM DUAL
UNION ALL SELECT 1, 'code3', 'aaa' FROM DUAL
UNION ALL SELECT 1, 'code4', 'ccc' FROM DUAL;
Query 2:
WITH ordered_codes ( rk_id, idx, string_value ) AS (
SELECT rk_id,
ROW_NUMBER() OVER ( PARTITION BY rk_id ORDER BY string_value ),
string_value
FROM table_with_codes
)
SELECT u.id,
MAX( CASE idx WHEN 1 THEN string_value END ) AS c1,
MAX( CASE idx WHEN 2 THEN string_value END ) AS c2,
MAX( CASE idx WHEN 3 THEN string_value END ) AS c3,
MAX( CASE idx WHEN 4 THEN string_value END ) AS c4
FROM users u
LEFT OUTER JOIN ordered_codes o
ON ( u.rk_id = o.rk_id )
WHERE u.id = 5234
GROUP BY u.id
| ID | C1 | C2 | C3 | C4 |
|------|-----|-----|-----|-----|
| 5234 | aaa | bbb | ccc | ddd |
Upvotes: 1