Home > Software design >  Select distinct on Capitals and remove uppercase and characters
Select distinct on Capitals and remove uppercase and characters

Time:11-15

I have a list of names in capitals and initials. i have removed the initails and removed the uppercase but distinct still shows them seperate (and it would be nice to get rid of the s of the end of the names.

SQL Oracle

SELECT DISTINCT (upper
     ( REGEXP_SUBSTR(NAME, '(\S )$'))) as NAMEZ,
    count(case when daysout is NULL then 1 else null end) as home,
    count(case when daysout is NOT NULL then 1 else null end) as away,
    count(*) as daystotal
    FROM peoplein

so what i get from this is

johns
johns
john
Jack
jack

before the reg and upper I used to get

Johns
JOHNS
John
Jack
JACK

I would like to just get them to be

john
jack

thank you for your help

CodePudding user response:

DISTINCT is not a function; it is a keyword that applies to all columns. In this case you want a GROUP BY clause instead of using DISTINCT:

SELECT UPPER( REGEXP_SUBSTR(NAME, '(\s|^)(\S ?)s?$', 1, 1, NULL, 2)) as name,
       COUNT(case when daysout is NULL then 1 else null end) as home,
       COUNT(case when daysout is NOT NULL then 1 else null end) as away,
       COUNT(*) as daystotal
FROM   peoplein
GROUP BY
       UPPER( REGEXP_SUBSTR(NAME, '(\s|^)(\S ?)s?$', 1, 1, NULL, 2))

or, using simple (faster) string functions:

SELECT TRIM(
         TRAILING 'S' FROM
         UPPER( SUBSTR(NAME, INSTR(NAME, ' ', -1)   1) )
       ) as name,
       COUNT(case when daysout is NULL then 1 else null end) as home,
       COUNT(case when daysout is NOT NULL then 1 else null end) as away,
       COUNT(*) as daystotal
FROM   peoplein
GROUP BY
       TRIM(
         TRAILING 'S' FROM
         UPPER( SUBSTR(NAME, INSTR(NAME, ' ', -1)   1) )
       )

(Although this latter query would trim multiple S characters from the end; however, that is fixable.)

Which, for the sample data:

CREATE TABLE peoplein(name, daysout) AS
  SELECT 'Abbot Alice', NULL FROM DUAL CONNECT BY LEVEL <= 3 UNION ALL
  SELECT 'Abbot Alice', 1    FROM DUAL CONNECT BY LEVEL <= 2 UNION ALL
  SELECT 'Baron Betty', 1    FROM DUAL CONNECT BY LEVEL <= 4 UNION ALL
  SELECT 'Count Chris', NULL FROM DUAL CONNECT BY LEVEL <= 5 UNION ALL
  SELECT 'Count Chris', 1    FROM DUAL CONNECT BY LEVEL <= 1 UNION ALL
  SELECT 'Doris',       1    FROM DUAL CONNECT BY LEVEL <= 6;

Both output:

NAME HOME AWAY DAYSTOTAL
ALICE 3 2 5
BETTY 0 4 4
CHRI 5 1 6
DORI 0 6 6

Note: Are you sure you want to remove a trailing S from a person's name?

fiddle

  • Related