Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I've wrapped the SQL into a function to make it easier to show some tests:</p> <p><a href="http://sqlfiddle.com/#!4/4c679/5" rel="nofollow">SQL Fiddle</a></p> <p><strong>Oracle 11g R2 Schema Setup</strong>:</p> <pre><code>CREATE TABLE mstuser ( id, gender, dob ) AS SELECT 1, 'M', SYSDATE - INTERVAL '1' YEAR FROM DUAL UNION ALL SELECT 2, 'M', SYSDATE - INTERVAL '2' YEAR FROM DUAL UNION ALL SELECT 3, 'M', SYSDATE - INTERVAL '3' YEAR FROM DUAL UNION ALL SELECT 4, 'F', SYSDATE - INTERVAL '1' YEAR FROM DUAL UNION ALL SELECT 5, 'F', SYSDATE - INTERVAL '2' YEAR FROM DUAL UNION ALL SELECT 6, 'F', SYSDATE - INTERVAL '3' YEAR FROM DUAL UNION ALL SELECT 7, 'F', SYSDATE - INTERVAL '4' YEAR FROM DUAL UNION ALL SELECT 8, 'F', SYSDATE - INTERVAL '5' YEAR FROM DUAL / CREATE OR REPLACE FUNCTION count_by_compare ( gender_compare mstuser.gender%TYPE, age_compare_group VARCHAR2 ) RETURN NUMBER AS user_count NUMBER; BEGIN SELECT COUNT(1) INTO user_count FROM mstuser a WHERE ( gender_compare IS NULL OR UPPER( a.gender ) = UPPER(gender_compare) ) AND ( age_compare_group IS NULL OR MONTHS_BETWEEN(sysdate, a.dob) / 12 BETWEEN TO_NUMBER( SUBSTR(age_compare_group, 1, INSTR(age_compare_group, '-') - 1) ) AND TO_NUMBER( SUBSTR(age_compare_group, INSTR(age_compare_group, '-') + 1) ) ); return user_count; END; / </code></pre> <p><strong>Query 1</strong>:</p> <pre><code>WITH Tests AS ( SELECT 'M' AS gender, '0-1' AS age FROM DUAL UNION ALL SELECT 'F', '0-6' FROM DUAL UNION ALL SELECT 'F', '0-1' FROM DUAL UNION ALL SELECT 'M', '0-6' FROM DUAL UNION ALL SELECT NULL, '0-2' FROM DUAL UNION ALL SELECT 'M', NULL FROM DUAL UNION ALL SELECT 'F', NULL FROM DUAL UNION ALL SELECT NULL, NULL FROM DUAL UNION ALL SELECT '', '' FROM DUAL ) SELECT gender, age, SUBSTR(age, 1, INSTR(age, '-') - 1), SUBSTR(age, INSTR(age, '-') + 1), count_by_compare( gender, age ) FROM Tests </code></pre> <p><strong><a href="http://sqlfiddle.com/#!4/4c679/5/0" rel="nofollow">Results</a></strong>:</p> <pre><code>| GENDER | AGE | SUBSTR(AGE,1,INSTR(AGE,'-')-1) | SUBSTR(AGE,INSTR(AGE,'-')+1) | COUNT_BY_COMPARE(GENDER,AGE) | |--------|--------|--------------------------------|------------------------------|------------------------------| | M | 0-1 | 0 | 1 | 1 | | F | 0-6 | 0 | 6 | 5 | | F | 0-1 | 0 | 1 | 1 | | M | 0-6 | 0 | 6 | 3 | | (null) | 0-2 | 0 | 2 | 4 | | M | (null) | (null) | (null) | 3 | | F | (null) | (null) | (null) | 5 | | (null) | (null) | (null) | (null) | 8 | | (null) | (null) | (null) | (null) | 8 | </code></pre> <p>Also, you don't need to test for <code>!= ''</code> as oracle represents an empty string as a <code>NULL</code> - see the final test above or the empty string comparisons below:</p> <pre><code>SELECT CASE WHEN '' = '' THEN 1 ELSE 0 END AS equal, CASE WHEN '' != '' THEN 1 ELSE 0 END AS not_equal, CASE WHEN '' IS NULL THEN 1 ELSE 0 END AS is_null, CASE WHEN '' IS NOT NULL THEN 1 ELSE 0 END AS is_not_null FROM DUAL </code></pre> <p>Gives the result:</p> <pre><code>| EQUAL | NOT_EQUAL | IS_NULL | IS_NOT_NULL | |-------|-----------|---------|-------------| | 0 | 0 | 1 | 0 | </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload