Use EXPLAIN in snowflake but on the results of another query. Using it on each row of the result - sql

So I want to get the tables used in the query_history table by using EXPLAIN on the query_text in the query_history. I know that I can give the SQL to EXPLAIN and it will give me the tables used but I need to do this over many different queries and return it all at once.
Basically I have 3 queries in the query_history table as follows:
select * from a.table1
select * from a.table2
select * from a.table3
And I need to do something like this:
SELECT "objects"
FROM TABLE(EXPLAIN_JSON(SYSTEM$EXPLAIN_PLAN_JSON(query_history.query_text)))
WHERE "operation"='TableScan';
This would return:
a.table1
a.table2
a.table3
I cannot do this in a programming language because it is going to be put into a BI tool that can only use SQL.

Related

Oracle SQL: single SELECT request for multiple owners

I would like your advice on the best method to use.
From a single Oracle server, we have 3 different owners that contain the exact same tables/data structures. Essentially, the owners allow us to separate the data by administrative regions.
Currently, when I want to do a SQL query on the entire data set (regions), I have to do 3 separate queries:
select * from owner1.Table1 union all
select * from owner2.Table1 union all
select * from owner3.Table1
In this simple example, there are no issues, but if the query is complex, it quickly becomes very difficult to maintain.
So, would there be a more efficient way to make only one global query instead of 3. I guess it's possible to do it via a PL/SQL script, or Dynamic SQL, but I don't know...
Basically, I would like to be able to do (where owners would contain the names of my 3 owners):
select * from owners.Table1
It is not possible to build views that would contain the data of all 3 owners (there would be too many).
Thanks
In this simple example, there are no issues, but if the query is complex, it quickly becomes very difficult to maintain.
So, would there be a more efficient way to make only one global query instead of 3.
Use a sub-query factoring clause (a.k.a. a CTE) to combine the queries with the simple UNION ALL queries and then perform the complex query on the combined table (rather than trying to perform the queries on the individual tables):
WITH subquery_name AS (
select * from owner1.Table1 union all
select * from owner2.Table1 union all
select * from owner3.Table1
)
SELECT <your complex query>
FROM subquery_name;

Select From Multiple and New Tables will be created

My Simple Query is
SELECT MAX(DATETIME)
FROM gss.dbo.contacts_23
WHERE Identification = ''
GROUP BY Identification
How can I select Max(date) from 25 tables and new tables can be created?
These tables like (contacts_22,contacts_25,contacts_29,contacts_36,.. and the new)
I tried to think as following
use union but what about the new tables will be created next time
select all tables start with 'contacts_' to fetch all these tables and the tables will be created next time
SELECT TABLE_NAME
FROM GSS.INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME like 'contacts_%'
but it's not doable with FROM clause
How can I do that GET MAX(DATE) FROM .... AND NEW TABLES
I'm using SQL Server 2012
Thanks in advance
The data model is horrible, and there is no clean way of achieving what you want.
The first way is to create a view which unions all your contacts_ tables, and then to run your query on that view.
Create view contacts_view as
select * from contacts_20
union
select * from contacts_21
...
This is the simplest solution, but only works if you can be certain that you're not creating more tables which need to be included in the view.
The alternative is to use dynamic SQL. This would use your query on the schema database to construct a SQL statement, which you then execute. This can get moderately complex, and is generally hard to test and debug, but does allow new tables to be automatically included in the results.

Rename all tables in SELECT query

Can anyone tell me how to replace the name of all the table names in a the SELECT/FROM statements?. I'm looking of a way that works well across vanilla queries as well as more complex ones with sub-queries and joins.
I.e.
New table name: new_table
Original query: SELECT * from table;
Result query: SELECT * FROM new_table;
Thanks a lot,
j
If your queries are as simple as what you're proposing, you should be able start by parsing the query which will give you a SqlSelect object. From there you can use getFrom to check if it's the table you want to change and setFrom to change it.
If you want to handle more complex queries, you should be able to implement the SqlVisitor interface to find all occurrences of the table to replace.

Trying to pull from multiple tables and multiple columns within tables

I have tried this query to pull up multiple tables and columns it works but comes back blank.
select * from onshore.contracting where code between 18789 and 18798;
select * from onshore.safety_incident where code between 18789 and 18798;
For your immediate problem, the following SQL will work if you really want all the data:
select * from onshore.contracting where code between 18789 and 18798;
select * from onshore.safety_incident where code between 18789 and 18798;
... and so on.
These tables probably have different columns so you need a separate select statement for each one.
If you are going to do more with SQL then it really would be worthwhile to learn it. There is a free resource here: https://www.w3schools.com/sql, my contribution is at http://www.thedatastudio.net and there are many others. It is a bit dangerous to use SQL without understanding it.

Select * from n tables

Is there a way to write a query like:
select * from <some number of tables>
...where the number of tables is unknown? I would like to avoid using dynamic SQL. I would like to select all rows from all the tables that (the tables) have a specific prefix:
select * from t1
select * from t2
select * from t3
...
I don't know how many t(n) might there be (might be 1, might be 20, etc.) The t table column structures are not the same. Some of them have 2 columns, some of them 3 or 4.
It would not be hard using dynamic SQL, but I wanted to know if there is a way to do this using something like sys.tables.
UPDATE
Basic database design explained
N companies will register/log in to my application
Each company will set up ONE table with x columns
(x depends on the type of business the company is, can be different, for example think of two companies: one is a Carpenter and the other is a Newspaper)
Each company will fill his own table using an API built by me
What I do with the data:
I have a "processor", that will be SQL or C# or whatever.
If there is at least one row for one company, I will generate a record in a COMMON table.
So the final results will be all in one table.
Anybody from any of those N companies will log in and will see the COMMON table filtered for his own company.
There would be no way to do that without Dynamic SQL. And having different table structures does not help that at all.
Update
There would be no easy way to return the desired output in one single result set (result set would have at least the same # of columns of the table with most columns and don't even get me started on data types compatibility).
However, you should check #KM.'s answer. That will bring multiple result sets.
to list ALL tables you could try :
EXEC sp_msforeachtable 'SELECT * FROM ?'
you can programmability include/exclude table by doing something like:
EXEC sp_msforeachtable 'IF LEFT(''?'',9)=''[dbo].[xy'' BEGIN SELECT * FROM ? END ELSE PRINT LEFT(''?'',9)'