Could you provide sample output that you want to get? Because it's hard to tell what you really need by looking at your question. For now, try this and provide feedback if it is what you are looking for:
CREATE TABLE contacts (
contact_name VARCHAR2(40),
contact_details VARCHAR2(20)
);
INSERT INTO contacts VALUES ('Acting Generals Office', 'ABCD');
INSERT INTO contacts VALUES ('BlackBerryOffice', 'A1B1');
INSERT INTO contacts VALUES ('Customer Care', 'A2B2');
INSERT INTO contacts VALUES ('D_Link Routers', 'A3B3');
COMMIT;
-- show all letters, even when there are no contacts belonging to any of them
WITH letters AS (
SELECT CHR(65 + level - 1) AS letter
FROM dual
CONNECT BY level <= ASCII('Z') - ASCII('A') + 1
)
SELECT lt.letter, ct.contact_name
FROM letters lt
LEFT JOIN contacts ct ON (lt.letter = UPPER(SUBSTR(ct.contact_name, 1, 1)))
ORDER BY 1, 2
;
Output:
LETTER CONTACT_NAME
------ ----------------------------------------
A Acting Generals Office
B BlackBerryOffice
C Customer Care
D D_Link Routers
E
F
.
.
.
Z
-- Output only those letters where there are associated contacts
SELECT SUBSTR(contact_name, 1, 1), contact_name
FROM contacts
ORDER BY 1, 2
;
Output:
SUBSTR(CONTACT_NAME,1,1) CONTACT_NAME
------------------------ ----------------------------------------
A Acting Generals Office
B BlackBerryOffice
C Customer Care
D D_Link Routers
Try at on SQLFiddle: SQLFiddle example