# sql | dev | automatic partitions for the lazy kind - automatic list partitioning

nah, using sample schema is way easier actually, lets go to ```HR```

lets say i want to make a stripped down table identical to the ```EMPLOYEES``` table, paritioned, by ```DEPARTMENT_ID``` column. so if i am using the ```HR.EMPLOYEES``` table, 
```
SELECT  COUNT(DISTINCT DEPARTMENT_ID)
  FROM  HR.EMPLOYEES;

/*
COUNT(DISTINCTDEPARTMENT_ID)
----------------------------
                          11
*/
```
i would need to create 11+1 (NULL) partitions (i like my NULLs separated), in the bad old way:

```
CREATE TABLE SYS.EMPLOYEES (
    EMPLOYEE_ID      NUMBER (6),
    FIRST_NAME       VARCHAR2 (20 BYTE),
    LAST_NAME        VARCHAR2 (25 BYTE),
    DEPARTMENT_ID    NUMBER (4)
)
PARTITION BY LIST(DEPARTMENT_ID)
(
    PARTITION DEPT_10 VALUES(10),
    PARTITION DEPT_20 VALUES(20),
    PARTITION DEPT_30 VALUES(30),
    PARTITION DEPT_40 VALUES(40),
    PARTITION DEPT_50 VALUES(50),
    PARTITION DEPT_60 VALUES(60),
    PARTITION DEPT_70 VALUES(70),
    PARTITION DEPT_80 VALUES(80),
    PARTITION DEPT_90 VALUES(90),
    PARTITION DEPT_100 VALUES(100),
    PARTITION DEPT_110 VALUES(110),
    PARTITION DEPT_NULL VALUES(NULL)
);
```
but this limits me to only values i defined in the table structure, we'll be getting errors if a new value shows up. ```DEFAULT```???
```
    .
    .
    PARTITION DEPT_DEFAULT VALUES(DEFAULT)
);
```
i would need to create 11 (DISTINCT) + 1 (NULL) + 1 (DEFAULT) partitions, in the bad old way:

```
DROP TABLE SYS.EMPLOYEES;

CREATE TABLE SYS.EMPLOYEES (
    EMPLOYEE_ID      NUMBER (6),
    FIRST_NAME       VARCHAR2 (20 BYTE),
    LAST_NAME        VARCHAR2 (25 BYTE),
    DEPARTMENT_ID    NUMBER (4)
)
PARTITION BY LIST(DEPARTMENT_ID)
(
    PARTITION DEPT_10 VALUES(10),
    PARTITION DEPT_20 VALUES(20),
    PARTITION DEPT_30 VALUES(30),
    PARTITION DEPT_40 VALUES(40),
    PARTITION DEPT_50 VALUES(50),
    PARTITION DEPT_60 VALUES(60),
    PARTITION DEPT_70 VALUES(70),
    PARTITION DEPT_80 VALUES(80),
    PARTITION DEPT_90 VALUES(90),
    PARTITION DEPT_100 VALUES(100),
    PARTITION DEPT_110 VALUES(110),
    PARTITION DEPT_NULL VALUES(NULL),
    PARTITION DEPT_DEFAULT VALUES(DEFAULT)
);

INSERT INTO  SYS.EMPLOYEES
    SELECT  EMPLOYEE_ID,
            FIRST_NAME,
            LAST_NAME,
            DEPARTMENT_ID
      FROM  HR.EMPLOYEES;
      
    COMMIT;

SELECT  COUNT(*)
  FROM  USER_TAB_PARTITIONS
 WHERE  TABLE_NAME = 'EMPLOYEES';
/*
  COUNT(*)
----------
        13
*/
```

what if there are 100 distincts? or 1000? 

i dont get paid enough for this, neither do i get to sleep peacefully or get vacations and stuff
 
now if i create the table with only the values i have now along with ```DEFAULT```, what if a large chunk of new values show up, ```DEFAULT``` will be huge then, and the purpose is ruined. i want them individually created, but, in an easier way. if your db is running 12.2 or higher, do give a kiss on DBA foreheads and thank your management (even if you dont want to, understandable, just pretend), use ```AUTOMATIC``` and dump the ```DEFAULT```. if a new value shows up, oracle will create a partition for it, automatically

```
DROP TABLE SYS.EMPLOYEES;

CREATE TABLE SYS.EMPLOYEES (
    EMPLOYEE_ID      NUMBER (6),
    FIRST_NAME       VARCHAR2 (20 BYTE),
    LAST_NAME        VARCHAR2 (25 BYTE),
    DEPARTMENT_ID    NUMBER (4)
)
PARTITION BY LIST(DEPARTMENT_ID) AUTOMATIC -- << this guy
(
    PARTITION DEPT_10 VALUES(10) --<<poof, the huge list is gone
);

INSERT INTO  SYS.EMPLOYEES
    SELECT  EMPLOYEE_ID,
            FIRST_NAME,
            LAST_NAME,
            DEPARTMENT_ID
      FROM  HR.EMPLOYEES;
      
    COMMIT;

SELECT  COUNT(*)
  FROM  USER_TAB_PARTITIONS
 WHERE  TABLE_NAME = 'EMPLOYEES';
/*
  COUNT(*)
----------
        12
*/
```

*there is always someone much lazier than you, looking for shortcuts*
