Oracle SQL query CONCAT, GROUP BY - sql

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.

Related

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?

BigQuery from column to rows by separator

I want to generate table and add all values per distinct id to one row using BigQuery
Example:
id label
000756f4-1af2-439b-b607-ce7384a6b8ee fast
000756f4-1af2-439b-b607-ce7384a6b8ee streaming
000756f4-1af2-439b-b607-ce7384a6b8ee other
0007bac4-1bed-4bf0-8b55-d21216723ef5 issue
000a03d2-f88c-4150-aa96-40b9fdaccb17 fast
000a03d2-f88c-4150-aa96-40b9fdaccb17 other
I would like to receive such table:
id label
000756f4-1af2-439b-b607-ce7384a6b8ee fast, streaming, other
0007bac4-1bed-4bf0-8b55-d21216723ef5 issue
000a03d2-f88c-4150-aa96-40b9fdaccb17 fast, other
Is it possible to achieve it with BigQuery?
You can just use string_agg():
select id, string_agg(label, ', ') as labels
from t
group by id;
Note that the ordering is arbitrary (and might even vary from one run to another). You might want to include an order by as well:
select id, string_agg(label, ', ' order by label) as labels
from t
group by id;
Update
Use string_agg:
select id, string_agg(label, ', ')
from mytable
group by id
Original answer
Use array_agg and array_to_string:
select id, array_to_string(array_agg(label), ', ')
from mytable
group by id

How to use LISTAGG and WHERE together

So I am trying to use a LISTAGG function while using a WHERE statement.
What I want to do is search by the WHERE statement and the LISTAGG returns a list with in relations to other columns.
In other words, when I use the WHERE statement with LISTAGG, I only get the value that I'm searching for. The other values associated with the other columns don't show up.
My script is kind of like this:
WITH TEST AS
(
SELECT DISTINCT
LOCATION,
ID,
LISTAGG (TOMATOCOUNT, ', ')
WITHIN GROUP (ORDER BY TOMATOCOUNT)
OVER (PARTITION BY LOCATION, ID) TOMATOTYPES,
FROM TOMATOLAND
)
SELECT
*
FROM TEST
WHERE (:TOMATOTYPE = TOMATO
OR :TOMATOTYPE IS NULL)
Filter on the result of LISTAGG strikes me as a bit backwords. Generally, if you're going to aggregate several items into a list, you're doing it at the last minute, for display purposes. ideally you would filter prior to the aggregation.
The following will return one row for each location/ID that contains the specified tomatotype.
SELECT DISTINCT
location,
id,
LISTAGG (tomatotype, ', ')
WITHIN GROUP (ORDER BY tomatocount)
OVER (PARTITION BY location, id)
tomatotypes
FROM tomatoland
WHERE (location, id) IN (SELECT location, id
FROM tomatoland
WHERE :tomatotype = tomatotype)
OR :tomatotype IS NULL
I think you want something like this:
WITH TEST AS (
SELECT LOCATION, ID,
LISTAGG(TOMATOTYPE, ', ') WITHIN GROUP (ORDER BY TOMATOCOUNT) OVER (PARTITION BY LOCATION, ID) as TOMATOTYPES
FROM TOMATOLAND
)
SELECT *
FROM TEST
WHERE ', ' || :TOMATOTYPE || ', ' LIKE '%,' || TOMATOTYPES || ', %' OR
:TOMATOTYPE IS NULL

Group query rows result in one result

I need make a query that I get the result and put in one line separated per comma.
For example, I have this query:
SELECT
SIGLA
FROM
LANGUAGES
This query return the result below:
SIGLA
ESP
EN
BRA
I need to get this result in one single line that way:
SIGLA
ESP,EN,BRA
Can anyone help me?
Thank you!
SELECT LISTAGG(SIGLA, ', ') WITHIN GROUP (ORDER BY SIGLA) " As "S_List" FROM LANGUAGES
Should be the listagg sequence you are needing
try
SELECT LISTAGG( SIGLA, ',' ) within group (order by SIGLA) as NewSigla FROM LANGUAGES
If you want to get the values grouped together in the order that Oracle produces the rows then:
SELECT LISTAGG( SIGLA, ',' ) WITHIN GROUP ( ORDER BY ROWNUM ) AS SIGLA
FROM LANGUAGES;
If you want alphabetical ordering then replace ORDER BY ROWNUM with ORDER BY SIGLA (or, curiously, ORDER BY NULL).

Postgres combine 2 columns and use group by

I have pat_first_name and pat_last_name columns in my psql database col. Id like to pick out most common names. I can do first names using
SELECT pat_first_name,count(pat_first_name)
from patients
GROUP BY pat_first_name
ORDER BY count DESC;`
However, when I try combine it fails
SELECT pat_first_name,pat_last_name,count((pat_first_name || ' ' || pat_last_name))
from patients
GROUP BY (pat_first_name || ' ' || pat_last_name)
ORDER BY count DESC;
column "patients.pat_first_name" must appear in the GROUP BY clause or be used in an aggregate function
where am I going wrong?
You can just do:
SELECT pat_first_name,pat_last_name,COUNT(*)
FROM patients
GROUP BY pat_first_name,pat_last_name
ORDER BY COUNT(*) DESC;
Or, if you really want the first_name and last_name concatenated in the result:
SELECT pat_first_name || ' ' || pat_last_name,COUNT(*)
FROM patients
GROUP BY pat_first_name || ' ' || pat_last_name
ORDER BY COUNT(*) DESC;
Either way, you gotta have the same "non-count" columns in the SELECT as in the GROUP BY.