select the inverse of sql result as a string list - select

having a sql e.g. something like the following resulting in some rows with one value.
I search a different sql than SELECT * FROM some_sql which results in one row with comma separated values.
WITH some_sql AS (
SELECT 1 FROM DUAL
UNION
SELECT 2 FROM DUAL
)
SELECT * FROM some_sql
this SQL results in the two rows with value 1 and 2.
I seach a SQl resulting in 1,2 without changing the code of 'some_sql'.

Consider http://halisway.blogspot.com/2006/08/oracle-groupconcat-updated-again.html

Sice you are on 11G you can use LISTAGG
WITH some_sql AS (
SELECT 1 x FROM DUAL
UNION
SELECT 2 x FROM DUAL
)
SELECT LISTAGG(x, ',') WITHIN GROUP(ORDER BY x) FROM some_sql

Related

How to aggregate all the resulted rows column data in one column?

I have a case driven query . Below is the simplest form
select Column 1 from mytable
Results :
Column 1
latinnametest
LatinManual
LatinAuto
Is it possible to show the aggregated data of column 1 data of all the resulted rows in another Column say column 5 in front of each row with comma separated ?
Expected :
Column 1 Column 2
latinnametest latinnametest,LatinManual,LatinAuto
LatinManual latinnametest,LatinManual,LatinAuto
LatinAuto latinnametest,LatinManual,LatinAuto
I have used array_agg and concat() but it aggregates the same row data in column 2 but not as expected to add all rows column data comma separated . Any help please.
Edit :
I have tried the solution mentioned below but I am getting repetitive data in the column . see the screenshot. I have hover the mouse over that last column and see the repetitive data . Any solution to this ?
[![enter image description here][1]][1]
You can use string_agg() as a window function:
select column_1,
string_agg(column_1, ',') over () as all_values
from the_table;
Edit, after the scope was changed:
If you need distinct values, use a derived table:
select column_1,
string_agg(column_1, ',') over () as all_values
from (
select distinct column_1
from the_table
) t;
Alternatively with a common table expression:
with vals as (
select string_agg(distinct column_1, ',') as all_values
from the_table
)
select t.column_1, v.all_values
from the_table t
cross join vals v

Postgres - Repeating an element N times as array

For example, where the element is 'hi', and where N is 3, I need a PostgreSQL snippet I can use in a SELECT query that returns the following array:
['hi', 'hi', 'hi']
Postgres provides array_fill for this purpose, e.g.:
SELECT array_fill('hi'::text, '{3}');
SELECT array_fill('hi'::text, array[3]);
The two examples are equivalent but the 2nd form is more convenient if you wish to replace the dimension 3 with a variable.
See also: https://www.postgresql.org/docs/current/functions-array.html
You may use array_agg with generate_series
select array_agg(s) from ( values('hi')) as t(s) cross join generate_series(1,3)
Generic
select array_agg(s) from ( values(:elem)) as t(s) cross join generate_series(1,:n)
DEMO
sql demo
with cte as (
select 'hi' as rep_word, generate_series(1, 3) as value
) -- ^^^ n = 3
select array(SELECT rep_word::text from cte);

How to have a custom sort order for a union query in Postgres

With a query like this (simplified for clarity):
SELECT 'East' AS name, *
FROM events
WHERE event_timestamp BETWEEN '2015-06-14 06:15:00' AND '2015-06-21 06:15:00'
UNION
SELECT 'West' AS name, *
FROM events
WHERE event_timestamp BETWEEN '2015-06-14 06:15:00' AND '2015-06-21 06:15:00'
UNION
SELECT 'Both' AS name, *
FROM events
WHERE event_timestamp BETWEEN '2015-06-14 06:15:00' AND '2015-06-21 06:15:00'
I want to customise the order of the resulting rows. Something like:
ORDER BY name='East', name='West', name='Both'
Or
ORDER BY
CASE
WHEN name='East' THEN 1
WHEN name='West' THEN 2
WHEN name='Both' THEN 3
ELSE 4
END;
However, Postgres complains with:
ERROR: invalid UNION/INTERSECT/EXCEPT ORDER BY clause
DETAIL: Only result column names can be used, not expressions or functions.
HINT: Add the expression/function to every SELECT, or move the UNION into a FROM clause.
Do I have any alternative?
Wrap it in a derived table (which is what "HINT: .... or move the UNION into a FROM clause" is suggesting)
select *
from (
... your union goes here ...
) t
order by
CASE
WHEN name='East' THEN 1
WHEN name='West' THEN 2
WHEN name='Both' THEN 3
ELSE 4
END;
I'd add an extra column showing the desired ordering, then use ordinal column positions in the ORDER BY, e.g.
SELECT 1, 'East' AS name, *
...
UNION ALL
SELECT 2, 'West' AS name, *
...
ORDER BY 1
Note that you probably also want UNION ALL since your added columns ensure that every set in the union must be distinct anyway.
By adding an extra column for ordering purpose, however it makes the UNION clause to work exactly as a UNION ALL (it does not eliminate duplicate rows from the result).

Postgresql is this 1 query or multiple?

I am new to postgresql (and SQL in general) and my biggest concern right now is optimization. Below I have a simple query. However I believe that it is just one query. However, it could also be the case that it is just 3 queries (the ones that exist new the union all). Or it might actually be 6 queries since there are actually 6 select statements.
with foo as (
select * from tableA
), bar as (
select * from tableB
), zeta as (
select * from tableC
)
select * from foo
union all
select * from bar
union all
select * from zeta
How many queries is the above query?
also...
The reason this question is important is because, I do not know whether I should write my query like the above or to simply just make all the queries separate.
select * from tableA; --query 1
select * from tableB; --query 2
select * from tableC; --query 3
Formally it is one complex query (as 'complex sentence'), which contains six 'simple' queries. You do not need these with statements though, as in fact they do nothing. Your first query should look like this:
select * from tableA
union all
select * from tableB
union all
select * from tableC;
In this case you'll obtain one set of rows as a result. If you execute
select * from tableA;
select * from tableB;
select * from tableC;
you will have three separate sets of rows.

How to transpose all rows into columns with particular column as header in sqlserver

I want to transpose each row of the table into different columns making one particular row as a header for the transposed table. Please help me out with this asap. Any simple example would be fine
Use PIVOT:
select
--userID, Stage1, Stage2, Stage3, Stage4
*
from (
select '1' as UserID,'1' as Stage,'1-1-2013' as [Date] union all
select '1','2','2-1-2013' union all
select '2','1','1-1-2013' union all
select '1','3','5-1-2013' union all
select '2','2','3-1-2013' union all
select '3','1','6-1-2013' union all
select '3','2','8-1-2013' union all
select '1','4','10-1-2013' union all
select '3','3','12-1-2013'
) x
pivot (
max([Date]) for Stage in ([1],[2],[3],[4],[5],[6])
) p
More about this topic:
http://blog.sqlauthority.com/2008/06/07/sql-server-pivot-and-unpivot-table-examples/