Postgresql conditionally include distinct in query - postgresql

Postgresql conditionally include distinct in query
Is there way to modify a query such as:
select distinct col1, col2
from our_schema.our_table
where (id = '1001')
The goal is to easily activate/deactivate the distinct keyword.
Obviously, one could move it to a comment such as:
select col1, col2 -- distinct
from our_schema.our_table
where (id = '1001')
Is there any easy way to do this in Postgresql?
I've seen 'dynamic SQL' in Microsoft SSMS using TSQL language.
Is there something like this for Postgresql? Or something even simpler?

Seems like this is just about code management / building SQL strings?
Insert a line break after DISTINCT. The only significance of white space in SQL is to separate tokens. Other than that, line breaks are purely cosmetic - except for standard comments starting with -- which end with the line.
SELECT DISTINCT
col1, col2 ...
-->
SELECT -- DISTINCT
col1, col2 ...
Or even:
SELECT
DISTINCT
col1, col2 ...
-->
SELECT
-- DISTINCT
col1, col2 ...
Or use C-style block comments: /* comment */
SELECT DISTINCT col1, col2 ...
-->
SELECT /*DISTINCT*/ col1, col2 ...

Related

Can the Custom SQL Query in a Tableau Dashboard accept a list of values in a Parameter?

I have a Tableau dashboard drawing data from a Vertica Database via a Custom SQL Query.
The database table contains more than 100 million rows, with a column COL1 indicated as primary key. Each COL1 value corresponds to exactly one row of data. Therefore COL1 is unique for all rows.
The Custom SQL Query below refreshes the dashboard whenever the parameter is updated.
SELECT COL1, COL2, COL3, COL4, COL5 FROM TABLE WHERE COL1=<Parameters.Col1Param>
Can the dashboard users input more than one value to get more than 1 row of data?
I have tried using the IN condition as below:
SELECT COL1, COL2, COL3, COL4, COL5 FROM TABLE WHERE COL1 IN (<Parameters.Col1Param>)
However, I can't seem to be able to make this work with Parameter values Param1;Param2;Param3 or Param1,Param2,Param3.
I also tried including all values of COL1 and allowing the user to filter on-the-fly, but the database table is too large (over 100M of rows) for the dashboard to load the data into memory.
As always, minutes after posting a question on StackOverflow, I find a reasonable answer to my question.
The answer to this can be found here: Convert comma separated string to a list
SELECT COL1, COL2, COL3, COL4, COL5 FROM TABLE WHERE COL1 IN (
SELECT SPLIT_PART(<Parameters.Col1Param>, ';', row_num) params
FROM (SELECT ROW_NUMBER() OVER () AS row_num FROM tables) row_nums
WHERE SPLIT_PART(<Parameters.Col1Param>, ';', row_num) <> ''
)

How to describe columns (get their names, data types, etc.) of a SQL query in PostgreSQL

I need a way to get a "description" of the columns from a SELECT query (cursor), such as their names, data types, precision, scale, etc., in PostgreSQL (or better yet PL/pgSQL).
I'm transitioning from Oracle PL/SQL, where I can get such description using a built-in procedure dbms_sql.describe_columns. It returns an array of records, one for each column of a given (parsed) cursor.
EDB has it implemented too (https://www.enterprisedb.com/docs/en/9.0/oracompat/Postgres_Plus_Advanced_Server_Oracle_Compatibility_Guide-127.htm#P13324_681237)
An examples of such query:
select col1 from tab where col2 = :a
I need an API (or a workaround) that could be called like this (hopefully):
select query_column_description('select col1 from tab where col2 = :a');
that will return something similar to:
{{"col1","numeric"}}
Why? We build views where these queries become individual columns. For example, view's query would look like the following:
select (select col1 from tab where col2 = t.colA) as col1::numeric
from tab_main t
http://sqlfiddle.com/#!17/21c7a/2
You can use systems table :
First step create a temporary view with your query (without clause where)
create or replace view temporary view a_view as
select col1 from tab
then select
select
row_to_json(t.*)
from (
select
column_name,
data_type
from
information_schema.columns
where
table_schema = 'public' and
table_name = 'a_view'
) as t

select all except for a specific column

I have a table with more than 20 columns, I want to get all columns except for one which I'll use in a conditional expression.
SELECT s.* (BUT NOT column1),
CASE WHEN column1 is null THEN 1 ELSE 2 END AS column1
from tb_sample s;
Can I achieve it in postgresql given the logic above?
It may not be ideal, but you can use information_schema to get the columns and use the column to exclude in the where clause.
That gives you a list of all the column names you DO want, which you can copy/paste into your select query:
select textcat(column_name, ',')
from information_schema.columns
where table_name ='table_name' and column_name !='column_to_exclude';

Postgres rule to substitute word in WHERE clause

Is it possible to replace a word within a WHERE clause of a SELECT statement by a rule (CREATE RULE myrule AS ON SELECT TO mytable...)?
SELECT col1, col2
FROM mytable
WHERE col2 = 1;
Should become
SELECT col1, col2
FROM mytable
WHERE col3 = 1;
The initial statement is issued by a client which does not allow the substitution. Hence the substitution has to be done on the database side.
** edit **
I might not have been specific enough.
I need a column name substitution for this kind of pattern of the select statement. The WHERE clause constantly changes. As well as the
Is it possible to refer to the current SELECT statement in the rule itself?
Broken down to the bare minimum this is what I need:
take the current SELECT statement (if it has this certain pattern)
replace "WHERE col2" with "WHERE col3"
packed into a rule which can be deployed on the database side of things
Use case when statement
SELECT col1, col2, col3
FROM mytable
WHERE CASE WHEN foo='bar' THEN col3 ELSE col1 END = 1;

how to create an extra column and rows using select query in postgresql

Following is a sample of what am trying to achieve (never mind the select query because it just to show my actual problem)
for example,
select col1 from(
select 'tab09' as col1
union
select 'tab09_01'
union
select 'tab09_02'
union
select 'tab09_03'
union
select 'tab09_04'
) t order by col1
will return
col1
----------
tab09
tab09_01
tab09_02
tab09_03
tab09_04
So, Which PostgreSQL function will helps to get the result like below
col1 col2
----------+----------
tab09 tab10
tab09_01 tab10_01
tab09_02 tab10_02
tab09_03 tab10_03
tab09_04 tab10_04
select col1,overlay(col1 placing '10' from 4 for 2) col2 from(
--your select query goes here
) t order by col1
       
overlay-postgresql doc
oh oh, i see a MAJOR problem here. UNION is definitely not what you want here. There is a major difference between UNION and UNION ALL. UNION automatically filters duplicates, which is not your goal. UNION ALL does an append. This is a very common mistake many SQL users tend to make. Here are some examples. I hope it helps: http://www.cybertec.at/common-mistakes-union-vs-union-all/
usually a UNION vs UNION ALL problems reaches my desk hidden as "performance problem".