SELECT * FROM (SELECT) - sql

There is a table "MAIN_TABLE" with columns "Table_Unique_Code" and "Table_name".
Also there are several tables with required data.
The task is to create SQL-query with parameter ("Table_Unique_Code"), which will select all data from the table determined by the "Table_Unique_code".
Something like
SELECT * FROM (*determine the name of the table by Table_Unique_code here*);
I tried
SELECT * FROM (SELECT table_name FROM MAIN_TABLE WHERE Table_Unique_Code=?)
but it doesn't work.
I work with OracleDB.

Related

BigQuery using Dynamic sql as the input source of a query

How can I use a dynamic query as an input source for a larger query?
There is a query I'm getting the union of values in different datasets/tables scattered around and the list is growing so I'm thinking of using the dynamic query than to write queries for each tables like this
SET QUERY = "";
SET tables = ["table1", "table2"...];
SET tables_size = ARRAY_LENGTH(tables);
WHILE i < tables_size DO
IF (i = tables_size -1) THEN
BEGIN
SET query = CONCAT(query, " SELECT id, name FROM ", tables[OFFSET(i)]);
BREAK;
END;
ELSE
SET query = CONCAT(query, " SELECT id, name FROM ", tables[OFFSET(i)], ' UNION ALL ');
END IF;
SET i = i + 1;
END WHILE;
EXECUTE IMMEDIATE query;
My goal is to use the output of the executed query as a FROM clause for a larger query.
It will be something like
Select A, B, C, D ... From *EXECUTE IMMEDIATE query* LEFT JOIN ... ON..
Is there a way to inject an output of a dynamic query as a table for another query?
I don't see TABLE as a variable type for bigquery so that was not my option.
I'm getting a bit tired of copy pasting table names to the exact query every time a new table is introduced to this logic.
SELECT id, name FROM table1 UNION ALL
SELECT id, name FROM table1 UNION ALL
SELECT id, name FROM table3...
If there is a simple way to do this? or maybe a reason to not use dynamic queries for performance reasons?
Hope one of these are helpful:
1. Wildcard tables
If tables you want to union have a common prefix, you can consider to use a wildcard table like below. I think this is more concise form rather than union-all:
-- Sample Tables
CREATE TABLE IF NOT EXISTS testset.table1 AS SELECT 1 AS id, 'aaa' AS name;
CREATE TABLE IF NOT EXISTS testset.table2 AS SELECT 2 AS id, 'bbb' AS name;
CREATE TABLE IF NOT EXISTS testset.table3 AS SELECT 3 AS id, 'ccc' AS name;
--- Wildcard tables
SELECT * FROM `testset.table*` WHERE _TABLE_SUFFIX IN ('1', '2', '3');
2. Dynamic SQL & Temp Table
You can't inject a dynamic SQL directly into another query but you can use a temp table to emulate it.
2.1 Dynamic SQL
More concise dynamic query to union all tables:
DECLARE tables DEFAULT ["testset.table1", "testset.table2", "testset.table3"];
SELECT ARRAY_TO_STRING(ARRAY_AGG(FORMAT('SELECT id, name FROM %s', t)), ' UNION ALL\n')
FROM UNNEST(tables) t;
2.2 Using a temp table
I thinks you can modify your larger query to use a dynamically generated temp table.
DECLARE tables DEFAULT ["testset.table1", "testset.table2", "testset.table3"];
CREATE TABLE IF NOT EXISTS testset.table1 AS SELECT 1 AS id, 'aaa' AS name;
CREATE TABLE IF NOT EXISTS testset.table2 AS SELECT 2 AS id, 'bbb' AS name;
CREATE TABLE IF NOT EXISTS testset.table3 AS SELECT 3 AS id, 'ccc' AS name;
EXECUTE IMMEDIATE (
SELECT "CREATE TEMP TABLE IF NOT EXISTS union_tables AS \n"
|| ARRAY_TO_STRING(ARRAY_AGG(FORMAT('SELECT id, name FROM %s', t)), ' UNION ALL\n') FROM UNNEST(tables) t
);
-- your larger query using a temp table
SELECT * FROM union_tables;
output:

thousands of values to be searched

simple search query
select * from table where id = id_1;
id_1,......................................id_2000
is there a way to search all these ids with one query or pl/sql code?
You could try:
SELECT * FROM table WHERE id IN (id_1, id_2, ... id_2000);
or if the IDs are strings:
SELECT * FROM table WHERE id IN ('id_'1, 'id_2', ... 'id_2000');

SQL Finding data from similar tables

I have a 50 tables with similar structures with name TABLE_1, TABLE_2, TABLE_3 etc. I want to select some information like SELECT * FROM TABLE WHERE CRM_ID = 100 but I dont know which table consists this ID. I guess that I should make a union with this tables and make a query from this union but I am afraid that it is not the best solution. Could anybody help me?
To find the table containing the field CRM_ID, you can use:
select TABLE_NAME
from SYS.ALL_TAB_COLUMNS
where COLUMN_NAME = 'CRM_ID'
From here, you can query the relevant tables with your union
select 'table_1', count(*) from table_1 where CMR_ID = 100
union all
select 'table_2', count(*) from table_2 where CMR_ID = 100
[.....]
If you have 50 tables, you may want to use some advanced text editing so you don't have to type the same line 50 times.
I can't see anything different from a UNION to get what you need.
However, I would like to avoid repeating all the code every time you need to query your tables, for example by creating a view:
create view all_my_tables as
select * from table1
union
select * from table2
...
and then
select *
from all_my_tables
where crm_id = 100
I would
create a view table_all as
select * from table_1 union all
select * from table_2 ...
but I guess you have 50 tables due to some performance reason like creating partitioning without partitioned table. If that is the case you need some table that simulates index and you need to have data "sorted". Then create table that contains: table_name, min_val, max_val:
table_1, 1, 1000
table_2, 1001, 2000
and procedure selecting looks like:
procedure sel(crmid) is
a varchar2(10);
value table%rowtype;
begin
select table_name into a from lookup where crmid between min_val and max_val;
execute immediate 'select * from ' || a || ' where crm_id = ' || crmid into value;
--do logic with value
end;
but if data is not ordered you need to iterate selects in loop. In such case use view.
Try this:
Select tmp.tablename from (
select 'table1' as tablename from table1 where CRM_ID=100
union all
select 'table2' as tablename from table2 where CRM_ID=100
) as tmp

Join on all fields without listing them?

Goal is to retrieve all exact records (each field is the same) from table_a that exist in table_b; however, there are many fields (lets say 100), which I don't want to type/list out.
Is there a way to compare tables based on records? Or have it auto-recognize and join-on fields when not specified?
SELECT * FROM table_a
WHERE EXISTS (
select * from table_b
-- where table_a.field1 = table_b.field1
-- and ...
-- and table_a.field100 = table_b.field100
);
try:
select * from A
intersect
select * from B
see: http://www.postgresql.org/docs/9.1/static/queries-union.html
modified as suggested by user2989408

SQl select specific column but with use of *

I need help, my SQL Server select statement is:
select * from schematemplate.scanner
the columns of this table are:
id
Asset_Category
Asset_Classification
Brand
Model
Supplier
Color
I can select all the columns except the Asset_Category and Asset_Classification by using this:
Select id, brand, model, supplier, color
from schematemplate.scanner
But I don't want to specify the columns that I will select like the code above.
Is it possible to use SELECT * from schematemplate.scanner and add a code like EXCEPT asset_category and asaset_classification?
Those are only five columns. Why not select it?
Anyway, here's a suggestion that you may take,
create a view and
run select on it,
example
CREATE VIEW viewScanner
AS
SELECT id, brand, model, supplier, color
FROM schematemplate.scanner
and when you want to select records,
SELECT * FROM viewScanner
You could do it dynamically, e.g.:
declare #s varchar(max) = 'select '
select #s=#s+name+',' from sys.columns
where object_id=object_id('schematemplate.scanner')
and name not in ('asset_category','asset_classification')
order by column_id
set #s=substring(#s,1,len(#s)-1)+' from schematemplate.scanner'
exec(#s)
sqlfiddle