Why is ORACLE throwing ORA-01790? - sql

I have a query with UNION ALL statements.
SELECT * FROM HULL_A
UNION ALL
SELECT * FROM HULL_B;
It throws the error
ORA-01790 "expression must have same datatype as corresponding
expression"
However, I checked that, and I think it is not the case. I used the following to check:
select db1.data_type, db2.data_type, db1.data_length, db2.data_length, db1.data_precision, db2.data_precision, db1.data_scale, db2.data_scale
from all_tab_columns db1
inner join all_tab_columns db2
on (db1.owner = db2.owner
and db1.column_name = db2.column_name)
where db1.table_name = 'HULL_A'
and db2.table_name = 'HULL_B'
and (
db1.data_type = db2.data_type
OR
db1.data_length = db2.data_length
)
The result is:
I was able to link HULL_A to HULL_C and HULL_D using UNION ALL.
So why is ORACLE throwing the error? What other test could I perform in order to be able to perform the UNION ALL?
I am working on WINDOWS 10 ORACLE 11g

Columns in both the table must have the same data type and order of the columns must be the same.
You can try the following query to identify the mismatch in columns of both the tables:
SELECT
A.COLUMN_ID COLUMN_HULL_A,
A.DATA_TYPE DATA_TYPE_HULL_A,
B.COLUMN_ID COLUMN_HULL_B,
B.DATA_TYPE DATA_TYPE_HULL_B
FROM
(
SELECT
COLUMN_ID,
DATA_TYPE
FROM
USER_TAB_COLUMNS
WHERE
TABLE_NAME = 'HULL_A'
) A
FULL OUTER JOIN (
SELECT
COLUMN_ID,
DATA_TYPE
FROM
USER_TAB_COLUMNS
WHERE
TABLE_NAME = 'HULL_B'
)B ON (A.COLUMN_ID = B.COLUMN_ID AND A.DATA_TYPE = B.DATA_TYPE)
WHERE
A.COLUMN_ID IS NULL
OR B.COLUMN_ID IS NULL;
Cheers!!

Related

Excluding a column from an inner join in PostgreSQL

I am trying to exclude a column (county) that is shared by both table so I can do a LEFT JOIN in a query. This is what I thought would work but there seems to be some issues (below produces the ERROR: syntax error at or near "LEFT"). What can I do to get this work?
CREATE TABLE levee_prioritization.svi_justice_communities_joined AS
SELECT * FROM ((SELECT COLUMN_NAME FROM information_schema.columns
WHERE table_schema = 'levee_prioritization'
AND table_name = 'svi2018_us_tract') AS allColumns
WHERE allColumns.COLUMN_NAME NOT IN ('county'))
LEFT JOIN levee_prioritization.justice40_communities b ON (a.fips =
LPAD(round(b.geoid_tract)::text, 11));
You didn't specify the view name for inner select:
CREATE TABLE levee_prioritization.svi_justice_communities_joined AS
SELECT * FROM (SELECT * FROM (SELECT COLUMN_NAME FROM information_schema.columns
WHERE table_schema = 'levee_prioritization'
AND table_name = 'svi2018_us_tract') AS allColumns
WHERE allColumns.COLUMN_NAME NOT IN ('county')) a
LEFT JOIN levee_prioritization.justice40_communities b
ON (a.fips = LPAD(round(b.geoid_tract)::text, 11));

Query to select all tables with specific last column Ibm Db2 z/os

Goal: I need to create a query to select all tables with specific last column Ibm Db2 z/os
So I know I need to change my where clause for this but pretty much I want to select all the tables in my schema that have the last column as BATCH_ID. I've tried a length based where clause but can't figure it out also I know MySQL has an ordinal position feature but that's not in IBM DB2 z/Os as far as I've seen. Any help would be appreciated.
select c.tabschema as schema_name,
c.tabname as table_name
from syscat.columns c
inner join syscat.tables t on
t.tabschema = c.tabschema and t.tabname = c.tabname
where c.colname = 'BATCH_ID' AND c.tabschema = 'WRIT5P1'
AND c.tabname not like 'OLD%'
and t.type = 'T'
order by schema_name, table_name;
SYSIBM.SYSTABLES
SYSIBM.SYSCOLUMNS
SELECT T.NAME AS TABLE_NAME
FROM SYSIBM.SYSTABLES T
JOIN SYSIBM.SYSCOLUMNS C ON C.TBNAME = T.NAME AND C.TBCREATOR = T.CREATOR
WHERE T.TYPE = 'T' AND T.CREATOR = 'WRIT5P1'
AND T.NAME NOT LIKE 'OLD%'
AND C.NAME = 'BATCH_ID'
AND C.COLNO = T.COLCOUNT
I don't remember if C.COLNO starts from 0 or 1. Edit the query accordingly, if it starts from 0.

Get column names and types grouped by column names

I have IBM DB2 database. I would like to get all column names, types length and scale grouped by table names.
To get all tables from schema XYZ:
select name
from SYSIBM.SYSTABLES
where creator = 'XYZ';
Now I can get colum descriptions for given table:
SELECT NAME, COLTYPE, LENGTH, SCALE
FROM SYSIBM.SYSCOLUMNS
WHERE TBNAME = 'sometablename'
I would like to group it:
SELECT NAME, COLTYPE, LENGTH, SCALE
FROM SYSIBM.SYSCOLUMNS
WHERE TBNAME in (select name from SYSIBM.systables where creator = 'XYZ')
GROUP BY table_names_from_schema_xyz;
How to do it?
Grouping (in the SQL sense) only makes sense in the context of aggregation functions.
I suspect what you are looking for is the output ordered by table name, then column name, so all columns of the same table are "grouped" together.
This query might work for you.
SELECT T.NAME AS TABNAME, C.NAME AS COLNAME, COLTYPE, LENGTH, SCALE
FROM SYSIBM.SYSTABLES T, SYSIBM.SYSCOLUMNS C
WHERE T.NAME = C.TBNAME
AND CREATOR = 'XYZ'
ORDER BY T.NAME, C.NAME;
Your question can be answered only from SYSCAT.COLUMNS
select tabname, colname, typename, length, scale
from syscat.columns
where tabschema = 'XYZ'
order by tabname, colno
Try inner join with SYSIBM.systables,probably the below example should work
select c.colname,
t.tabname as tables, COLTYPE, LENGTH, SCALE
from SYSIBM.SYSCOLUMNS c
inner join SYSIBM.systables t on
t.tabschema = c.tabschema and t.tabname = c.tabname
where t.type = 'T'
and t.tabschema = 'XYZ'
order by c.colname;

DB2 SQL Show Long and Short Table Names?

I've started creating descriptive table names in DB2 and have found DB2 has a short name and a long name for each table.
EmployeePlan has a short name of Emplo00001
I would like to be able to display both names from a sql statement.
Here's my existing SQL -- is there a table I can join to in order to get the short name?
select * --table_name, system_column_name, column_text, Type_Name, column_Size, *
from sysibm.SQLColumns
where table_schem IN ('LAWMOD9T', 'LIBDDS')
and upper(table_name) IN ('EMPLOYEEPLAN')
ORDER BY system_column_name
And thank you, Darius X for answering my question so quickly. Here's my final query:
SELECT b.system_table_name as ShortName,
a.table_name, a.system_column_name, a.column_text,
a.type_name, a.column_size
FROM sysibm.SQLColumns a
INNER JOIN qsys2.systables b
ON a.table_name = b.table_name
AND a.table_schem = b.table_schema
WHERE UPPER(a.table_schem) IN ('LAWMOD9T', 'LIBDDS')
AND UPPER(a.table_name) IN ('EMPLOYEEPLAN')
ORDER BY a.table_schem, a.table_Name, a.ordinal_position
There may be more than one way, but if you run this query:
select *
from qsys2.systables
where table_schema IN ('LAWMOD9T', 'LIBDDS')
You'll see that SYSTEM_TABLE_NAME is one of the columns. So, you can join to qys2.systables using the schema and "long" table name.
You can add too the short name filter too
select
TABLE_NAME
from QSYS2.SYSTABLES
where table_schema = 'SchemaName' AND SYSTEM_TABLE_NAME = 'SystemName';

select column which is another table column value

selecting column which is another table column value.what's wrong with this query
select
geoName
from
hgeo h
where
geoName not in (select (select column_name
from information_schema.columns
where ((column_name = h.levelName) and (table_Name = 'flatgeo')))
from flatgeo)
I think there is some problem
(select
(select column_name
from information_schema.columns
where ((column_name = h.levelName) and (table_Name = 'flatgeo')))
How to write it?
You can't use meta-information to change the shape of your query. Unless you want to go down the dynamic sql route (which can quickly get complex), I'd go for the following:
SELECT
geoName
FROM hgeo h
WHERE
NOT EXISTS (SELECT * FROM flatgeo f
WHERE
(h.levelName = 'value1' and f.value1 = h.geoName) OR
(h.levelName = 'value2' and f.value2 = h.geoName)
//Repeat for each possible levelName value.
)
you can try this
select GeoName from HGeo where HGeo.GeoName not in
(select FlatGeo.value1 from FlatGeo union
select FlatGeo.value2 from FlatGeo union
select FlatGeo.value3 from FlatGeo)
You should use tablename before your column geoname. Like hgeo.geoname.
do you want to find out the geoname of hgeo that are not in flatgeo?