oracle equivalent of hive collect_set function - sql

What is the oracle equivalent of below hive query?
select appn_id,collect_set(CONCAT(upper(TRIM(dcsn_type_nm)),':',upper(TRIM(dcsn_outcm_nm))))
FROM <left join between few tables>
group by appn_id
EDIT:
Updated based on Gordon's answer -
select appn_id,listagg(upper(trim(dcsn_type_nm)) || ':' || upper(trim(dcsn_outcm_nm))) within group (order by null) set_type_outcm_nm
FROM <left join between few tables>
group by appn_id

I think the way this is being used, the equivalent is listagg():
select listagg(upper(trim(dcsn_type_nm)) || ':' || upper(trim(dcsn_outcm_nm))) with group (order by null)
listagg() is an aggregation function, so it combine data from multiple rows.

Related

Oracle SQL query CONCAT, GROUP BY

I have this table
I wanted to sort by POS ASC and also aggregate the two columns X,Y so that my ID becomes Unique. So the result should be like this.
I tried for many hours and I could aggregate the column X,Y. But when I'm doing a GROUP BY ID and then WMCONCAT(X,Y) I couldn't sort it by the POS col....
Any help maybe..? Thanks.
Instead of using WM_CONCAT, try using the LISTAGG aggregate function: it allows you to specify an ordering of your choice:
SELECT ID,
LISTAGG('(' || X || ', ' || Y || ')', ', ') WITHIN GROUP (ORDER BY POS) AS XY
FROM tab
GROUP BY ID
Check the demo here.

Oracle: Generate WHERE clause from resultset ids?

In Toad for Oracle 12:
I've selected rows from a table using a complex query.
I want to select those same rows in the system's application's WHERE clause.
However, the application doesn't support full SELECT statements, only WHERE clauses. And occasionally, it doesn't allow complex queries as subqueries in the WHERE clause, which is the case for my current query.
As an alternative, is there a way to get Toad to generate a WHERE clause from the resultset's IDs?
I would copy/paste the WHERE clause into the application. This is a common task, so it would be nice if there was something easy like a button in Toad that would do this.
Example:
Use the resultset...
ID VAL
1 A
2 B
3 C
...to generate a WHERE clause:
where id in (1,2,3)
Or if the IDs are text:
where id in ('1','2','3')
You can apply listagg function to your output and concatenate output IDs to list:
with a as (
<your_current_query>
)
select 'where id in ('
|| listagg(id, ',') within group(order by id)
|| ')' as where_clause
from a
You can use a subquery in the where clause:
where id in (select id
from . . . -- your complicated query here
)
Here is Maximo-specific version of #astentx's query:
with a as (
<<your query>>
)
select 'wonum in ('''
|| listagg(wonum, ''', ''') within group(order by wonum)
|| ''')' as where_clause
from a
And this query uses the syntax for Maximo's filtering fields:
with a as (
<<your query>>
)
select '='
|| listagg(attributename, ', =') within group(order by attributename)
|| '' as where_clause
from a
Related:
LISTAGG in Oracle to return distinct values
SQL Server: Generate WHERE clause from resultset ids?

SQL Group By subquery in postgresql

I want to group by the foolowing table but I also need to group the column ID as depitected on the image.
SELECT SUM(ml),sku,name FROM consumos
GROUP BY sku,name
ORDER BY name
Any ideas?
Best regards
Looks like you want a JSON array. This can be done using jsonb_agg():
select name, sku, ml, jsonb_agg(id)
from the_table
group by name, sku, ml;
In standard SQL, this would look like:
select name, sku, ml,
'[' || listagg(id, ',') within group (order by id) || ']' as ids
from t
group by name, sku, ml
order by name, count(*);
However, not all databases support that standard operator || for string concatenation. And not all databases call their string aggregation operator listagg(). So you might need to tweak the query for your database.
EDIT:
In Postgres, this would be:
select name, sku, ml,
'[' || string_agg(id, ',' order by id) || ']' as ids
from t
group by name, sku, ml
order by name, count(*);

String formatting using LISTAGG in Oracle. Escaping single quote ` ' `

How can I format the output of listagg in Oracle to produce output(every field in the single quote) as 'student1', 'student2', 'student3'.
I have gone through documentation and other question on listagg but can't find much.
SQL Query to concatenate column values from multiple rows in Oracle
SELECT LISTAGG(student_name,',') WITHIN GROUP (ORDER BY student_name)
from students
Thanks
You could use:
SELECT LISTAGG('''' || student_name || '''',',')
WITHIN GROUP (ORDER BY student_name)
FROM students;
or using ENQUOTE_LITERAL function:
SELECT LISTAGG(DBMS_ASSERT.ENQUOTE_LITERAL(student_name),',')
WITHIN GROUP (ORDER BY student_name) AS r
FROM students;
DBFiddle Demo
This should do the job. You need to escape the ' in the query.
SELECT LISTAGG('''' || student_name || '''',', ') WITHIN GROUP (ORDER BY student_name)
FROM students

Aggregate strings in descending order in a PostgreSQL query

In addition to the question How to concatenate strings of a string field in a PostgreSQL 'group by' query?
How can I sort employee in descending order?
I am using PostgreSQL 8.4 which doesn't support string_agg(). I've tried to use the following, but it isn't supported:
array_to_string(array_agg(employee ORDER BY employee DESC), ',')
I'd appreciate any hint to the right answer.
In PostgreSQL 9.0 or later you can order elements inside aggregate functions:
SELECT company_id, string_agg(employee, ', ' ORDER BY company_id DESC)::text
FROM tbl
GROUP BY 1;
Neither string_agg() nor that ORDER BY are available for PostgreSQL 8.4. You have to pre-order values to be aggregated. Use a subselect or CTE (pg 8.4+) for that:
SELECT company_id, array_to_string(array_agg(employee), ', ')
FROM (SELECT * FROM tbl ORDER BY company_id, employee DESC) x
GROUP BY 1;
I order by company_id in addition as that should speed up the subsequent aggregation.
Less elegant, but faster. (Still true for Postgres 14.)
See:
Concatenate multiple result rows of one column into one, group by another column
Alternatives to array_agg()?