How to find null and empty columns in a table with SQL - sql

I am using Oracle SQL developer, We are loading tables with data and I need to validate if all the tables are populated and if there are any columns that are completely null(all the rows are null for that column).
For tables I am clicking each table and looking at the data tab and finding if the tables are populated and then have looking through each of the columns using filters to figure out if there are any completely null columns. I am wondering if there is faster way to do this.
Thanks,
Suresh

You're in luck - there's a fast and easy way to get this information using optimizer statistics.
After a large data load the statistics should be gathered anyway. Counting NULLs is something the statistics gathering already does. With the default settings since 11g, Oracle will count the number of NULLs 100% accurately. (But remember that the number will only reflect that one point in time. If you add data later, the statistics must be re-gathered to get newer results.)
Sample schema
create table test1(a number); --Has non-null values.
create table test2(b number); --Has NULL only.
create table test3(c number); --Has no rows.
insert into test1 values(1);
insert into test1 values(2);
insert into test2 values(null);
commit;
Gather stats and run a query
begin
dbms_stats.gather_schema_stats(user);
end;
/
select table_name, column_name, num_distinct, num_nulls
from user_tab_columns
where table_name in ('TEST1', 'TEST2', 'TEST3');
Using the NUM_DISTINCT and NUM_NULLS you can tell if the column has non-NULLs (num_distinct > 0), NULL only (num_distinct = 0 and num_nulls > 0), or no rows (num_distinct = 0 and num_nulls = 0).
TABLE_NAME COLUMN_NAME NUM_DISTINCT NUM_NULLS
---------- ----------- ------------ ---------
TEST1 A 2 0
TEST2 B 0 1
TEST3 C 0 0

Certainly. Write a SQL script that:
Enumerates all of the tables
Enumerates the columns within the tables
Determine a count of rows in the table
Iterate over each column and count how many rows are NULL in that column.
If the number of rows for the column that are null is equal to the number of rows in the table, you've found what you're looking for.

Here's how to do just one column in one table, if the COUNT comes back as anything higher than 0 - it means there is data in it.
SELECT COUNT(<column_name>)
FROM <table_name>
WHERE <column_name> IS NOT NULL;

This query return that what you want
select table_name,column_name,nullable,num_distinct,num_nulls from all_tab_columns
where owner='SCHEMA_NAME'
and num_distinct is null
order by column_id;

Below script you can use to get empty columns in a table
SELECT column_name
FROM all_tab_cols
where table_name in (<table>)
and avg_col_len = 0;

Related

(Oracle SQL, PLSQL) How to delete columns, which are entirely NULL

I have a question regarding my Oracle SQL / PLSQL Table:
I have a Table with Values. Some of the Columns have no Values in all Rows at all. How do I therefore delete these columns, which are entirely NULL?
incase someones suggestion includes to transpose the tablem its too difficult for me to use Pivot, because the values are too different.
The Table has about 40 columns and 121 Rows.
Thank you very much.
EDIT: what i meant was, it would be great if the empty columns could be "automatically" be detected and deleted/removed/deselected.
You can identify the columns using aggregation. Here is one method that puts the names in a single column:
select ((case when count(col1) = 0 then 'col1,' end) ||
(case when count(col2) = 0 then 'col2,' end) ||
. . .
) as cols
from t;
Then you can use alter table to actually drop the columns.

Oracle SQL query to get columns which has values

I have user table with 100+ columns where some of the columns has null values depending on user type in the table. I am looking for SQL query to list the rows which has values in columns for particular user type. I have seen certain examples but those queries has specific column name in condition. In my situation, i have many columns that can be null. Can some one help me with the query?
Thanks
If you have Oracle Statistics enabled, (i belive they are always enabled in 11g), you can use the NUM_DISTINCT column of user_tab_columns:
Generate testing table and populate:
CREATE TABLE TESTING (
JOE VARCHAR2(200),
FREDDY VARCHAR2(200),
CAR NUMBER );
INSERT INTO TESTING VALUES ('1', 'x', NULL);
INSERT INTO TESTING VALUES ('b', '2', NULL);
COMMIT;
ANALYZE TABLE TESTING COMPUTE STATISTICS;
The Query you need:
SELECT * FROM USER_TAB_COLUMNS WHERE TABLE_NAME = 'TESTING' AND NUM_DISTINCT <> 0

How to update multiple records in a table?

I need to update the column B in a table, which has a column A as the primary key, with the a different value for each value in column A. There are about 50,000 rows to be updated in the table, which makes it impossible to do this manually. Is there any other way to update it?
Of all the records in the table, I want to update just 50000. For each record among these 50,000, the value to be updated is different. How can I update the table without having to write 50,000 update queries?
Column A. Column B
One. 1
Two 2
Three 3
I want to update one=4, two=5 and so on for about 50,000 rows.
Thanks in advance guys!
I don't know whether I got your requirement properly but i have written a below working snippet to replicate the scenario. Let me know if this helps
--Drop any existing table if present with same name
DROP TABLE SIMPLE_UPDATE;
--Create new table
CREATE TABLE SIMPLE_UPDATE
(
COL1 NUMBER,
COL2 VARCHAR2(2000 CHAR)
);
-- Inserting random test data
INSERT INTO SIMPLE_UPDATE
SELECT LEVEL,TO_CHAR(TO_DATE(LEVEL,'J'),'JSP') FROM DUAL
CONNECT BY LEVEL < 500;
-- Updating the col2 value assuming thta the increment is adding 3 to each number and updating the col2 with the same.
UPDATE SIMPLE_UPDATE
SET COL2 = COL1+3
WHERE <COL_NAME> = <CONDITON>;
COMMIT;

ORA-00947 - not enough values: Occurs in one server but not another

I am work on a project which has to add one column to the exist table.
It is like this:
The OLD TBL Layout
OldTbl(
column1 number(1) not null,
column2 number(1) not null
);
SQL TO Create the New TBL
create table NewTbl(
column1 number(1) not null,
column2 number(1) not null,
**column3 number(1)**
);
When I try to insert the data by the SQL below,
on one oracle server,it was successful executed,
but on another oracle server, I got "ORA-00947 error: not enough values"
insert into NewTbl select
column1,
column2
from OldTbl;
Is there any oracle option may cause this kind of difference in oracle?
ORA-00947: not enough values
this is the error you received, which means, your table actually has more number of columns than you specified in the INSERT.
Perhaps, you didn't add the column in either of the servers.
There is also a different syntax for INSERT, which is more readable. Here, you mention the column names as well. So, when such a SQL is issued, unless a NOT NULL column is missed out, the INSERT still work, having null updated in missed columns.
INSERT INTO TABLE1
(COLUMN1,
COLUMN2)
SELECT
COLUMN1,
COLUMN2
FROM
TABLE2
insert into NewTbl select
column1,
column2
from OldTbl;
The above query is wrong, because your new table has three columns, however, your select has only two columns listed. Had the number and the order of the columns been same, then you could have achieved it.
If the number of the columns, and the order of the columns are different, then you must list down the column names in the correct order explicitly.
I would prefer CTAS(create table as select) here, it would be faster than the insert.
CREATE TABLE new_tbl AS
SELECT column1, column2, 1 FROM old_tbl;
You could use NOLOGGING and PARALLEL to increase the performance.
CREATE TABLE new_tbl NOLOGGING PARALLEL 4 AS
SELECT column1, column2, 1 FROM old_tbl;
This will create the new table will 3 columns, the first two columns will have data from the old table, and the third column will have value as 1 for all rows. You could keep any value for the third column as per your choice. I kept it as 1 because you wanted the third column as data type NUMBER(1).

Find columns with NULL values in Teradata

I would like to find the columns in a table that has a null value in it.
Is there a system table that have that information?
To find columns where "null" values are allowed try...
select *
from dbc.columns
where databasename = 'your_db_name'
and tablename = 'your_table_name'
and Nullable = 'Y'
then to identify the specific rows w/ null values, take the "ColumnName" from the previous result set and run queries to identify results... perhaps throw them in a volatile table if you want to take further action on them (update,delete).
-- for example you found out that column "foo" is nullable...
create volatile table isnull_foo_col
as
(
sel *
from your_table_name
where foo is null
) with data
on commit preserve rows;
If you have statistics collected on the column you can use the views found here for Teradata 12.0.03+ and Teradata 13.0.02+ to determine the number of records in the table that have NULL values.
In Teradata 14, if you use the SHOW STATISTICS with the VALUES clause you will get similar information generated by the views listed at the link above.
You can use the DBC.Columns data dictionary view to determine what columns in a particular table are nullable.