How to select all columns not containing a certain substring in Postgresql? - sql

If I have a table with column names like that:
name,
name_raw,
item,
item_raw,
message,
message_raw
...
... etc.
How can I select every column that does not end with _raw dynamically?
Is something like this:
SELECT
[SOME REGEX LOGIC HERE]
FROM
mytable
or similar possible?

If you have so many columns that you cannot write a (static) query, you probably have to change the schema of your db.
If you cannot change the schema, here's a quick and dirty solution that utilizes postgresql's JSON capabilities. It does not return a traditional table with multiple columns, instead it returns a single column that contains json objects which contain all the columns from the original table whose name ends with _raw.
SELECT (
SELECT json_object_agg(key,value)
FROM json_each(to_json(t))
WHERE key ~ 'raw$'
) FROM mytable;
The idea is convert every row from mytable to a JSON object and then use JSON functions to filter the members of the object.

Use the information schema e.g.
SELECT column_name
FROM information_schema.columns
WHERE table_schema = 'my_schema'
AND table_name = 'mytable'
AND NOT column_name LIKE '%\_raw'
note because the underscore itself is a query wildcard it needs to be "escaped"

Related

How to select the same column from multiple table with almost same name in SQL?

I'd like to select a 2 column from lot of table.
Exemple
Table_2017-01
id name value
Table_2017-02
id name value
Table_2017-03
id name value
etc...
My Query would be
SELECT name, value
FROM Table_2017-01, Table_2017-02, Table_2017-03
But I'd like to know if something it's possible like
SELECT name, value FROM LIKE Table_%
I know this last query is not possible and it could be easier for me if a query exist for this problem as I can have a lot of table with just a part of the name different.
To select mutiple columns with the same name you have to the table as prefix like:
SELECT `Table_2017-01.name`, `Table_2017-02.name`, `Table_2017-03.name` FROM Table_2017-01,`Table_2017-02, Table_2017-03
If you want them in one Column, use Union.
(SELECT `Table_2017-01.name` from Table_2017-01)
Union
(SELECT `Table_2017-02.name` from Table_2017-02)
It depends on your database. Oracle f.e. has a data dictionary with all tables.
Because I know oracle better than others I use this for the example:
SELECT TABLE_NAME FROM ALL_TABLES WHERE TABLE_NAME LIKE 'Table_2017-%';
Now there are the following ways I sometimes use:
I build a list of selects and fire them into the database:
via Excel (not explained here)
via SQL
SELECT
'SELECT '''||TABLE_NAME||''' TABLE_NAME, NAME, VALUE FROM '||
TABLE_NAME
||' UNION '
FROM ALL_TABLES WHERE TABLE_NAME LIKE 'Table_2017-%';
Now you can copy the result to your database (dont forget to delete the last "UNION")
via program (python, Lazarus, c# .. whatever, same view is needed)
But pay attention: It is quick and dirty, the column names and types have to match.

Select columns containing string

Is it possible to retrieve all data in columns containing a particular string? I do not have any control over the data structure and I rather shorten my code than to type everything if possible. As far as I know statements as LIKE and CONTAIN are only used to retrieve particular rows instead of columns. Lets say I have a table with column names: time, run1, run2, run3, ....., run 34, I would like to use something like:
SELECT columns FROM [Tablename] WHERE columns CONTAIN 'run';
Is this possible?
Thanks!
Use like.
In Oracle, you could do
SELECT column_name
from all_tab_columns
where table_name = 'YOUR_TABLE'
and lower(column_name) like 'run%'
In SQL Server, you could do
SELECT column_name
from information_schema.columns
where table_name = 'YOUR_TABLE_NAME'
and lower(column_name) like 'run%'

Retrieve Column names From one table that contain 'report'

I need to know the column names of my table exchangecondition that contains "report" in their names. I tried to use USER _TAB_COLUMNS but that didn't work, because I get no rows selected with this query:
select * from USER_TAB_COLUMNS;
However, if I could get rows when I use USER_TAB_COLUMNS, I can use this query:
SELECT column_name FROM USER_TAB_COLUMNS WHERE table_name = 'exchangecondition' and column_name like '%report%'.
Can someone help me please?
Instead of using user_tab_columns, use all_tab_columns, provide table name and column name in upper case, provide owner name (incase you know it already).

Selecting column names and table names of a select statement

How can I select the column name and table name from a SQL?
I tried something like this but it didn't work:
select column_name, table_name from (select * from users);
This might sound silly, but I have a list of different SQLs and I need to extract their columns and tables into a list. So some of the statements could me:
select username, password from users
select createdate from userlog
select * from dept
...
If I can select the column name and table name of a select statement, then I should get, say for the first statement, username and password for columns and users for table name. And createdate for column and userlog for table name in the second statement.
Then if it all works, I can then loop through the list of select statements and extract their column and table names.
The below query worked for Oracle database.
SELECT COLUMN_NAME,TABLE_NAME FROM ALL_TAB_COLUMNS
You can see more about information-schema
Edit:
You may try like this:
SELECT COLUMN_NAME,TABLE_NAME FROM ALL_TAB_COLUMNS
WHERE TABLE_NAME IN (SELECT ColumnName FROM users)
You need to parse the SQL statement so the SQL engine figures out the columns and datatypes of the columns that the statement returns.
How you do it best depends on what environment you are using. In some programming languages when you create a SqlPreparedStatement or OraCommand or whatever the object may be called, that object may have a metadata collection populated with column information after parsing.
If you are doing it in the database itself, parsing your statement with DBMS_SQL can get you the information you need. See Example 8 in the documentation at this link:
http://docs.oracle.com/database/121/ARPLS/d_sql.htm#ARPLS68205
--
Oh, and this gives you column names of the select statement. The table names I do not know of any way to get easily.

Sequence restrictions of SELECT statement

In my table I have a column of type nVarchar or nText
Suppose value of a this col is like this '... xxx yyy zzz ...'
I use SELECT to search table with this column
SELECT * FROM tbl_name WHERE col_name like '%xxx yyy%'
Since the I can't force users to enter words with my sequence I want to give same result with this query too:
SELECT * FROM tbl_name WHERE col_name like '%yyy xxx%'
It looks to me like you might want to consider normalizing your table. Specifically, if "yyy xxx" is the same as "xxx yyy", you're storing an array (or list or whatever you want to call it) in one column, which breaks first normal form. Normalize it so that each of those atoms (i.e. "xxx", "yyy") are stored separately and are related back to your original record. Then it's almost trivial to do the kind of thing you're looking to do.
You have to tokenize the user input into separate words inside your application code (not in sql) and then construct queries like
SELECT * FROM tbl_name WHERE
(col_name like '%yyy%') AND (col_name like '%xxx%') AND ...
Your best bet is to use both criteria, and "OR".
SELECT *
FROM tbl_name
WHERE (col_name like '%xxx yyy%')
OR (col_name like '%yyy xxx%');