How should I proceed after running the collect command? - sql

Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production.
I have a table in the below format.
Number User Value
-------------------
1 A 25
1 B 28
2 C 30
2 D 35
This is what I want:
Number User Value
-------------------
1 A,B 25,28
2 C,D 30,35
I tried using a Listagg but it gives me ORA-01489: result of string concatenation is too long.
This was the listagg command:
SELECT "Number",
LISTAGG ("user", ', ') WITHIN GROUP (ORDER BY "user") "user",
LISTAGG ("value", ', ') WITHIN GROUP (ORDER BY "user") VALUE
FROM table
GROUP BY "Number";
I cant create type as I dont have privileges. In one of the other similar questions, someone suggested using collect. So using this:
SELECT number, CAST (COLLECT (USER) AS SYS.DBMSOUTPUT_LINESARRAY)
FROM emp
GROUP BY number;
I dont know where to go from here. When I run this query, I get this column:
CAST(COLLECT(USER)ASSYS
-----------------------
COLLECTION
COLLECTION
COLLECTION
As you can see my sql knowledge is very minimal. Any help would be much appreciated!

Try using the xmlagg approach:
rtrim(xmlagg(xmlelement(e, name1 || ',')).extract('//text()').getclobval(), ',')
Here is a sqlfiddle demo

Related

I am having Issues counting values in a row with separators using SQL

I am new to snowflake and trying the count the number of values in a row with separators using SQL. I am not sure how to go about it. I've googled solutions for this but have not been able to find one.
table name: Lee_tab
user
names
id01
Jon;karl;lee;
id02
Abi;jackson;
id03
don;
id04
what I want to achieve
user
names
name_count
id01
Jon;karl;lee;
3
id02
Abi;jackson;
2
id03
don;
1
id04
0
Here is three solutions using REGEXP_COUNT, SPLIT, ARRAY_SIZE, STRTOK_TO_ARRAY (I would use the REGEXP_COUNT one):
SELECT
column1,
column2,
regexp_count(column2, ';')+1 as solution_1,
ARRAY_SIZE(split(column2, ';')) as solution_2,
ARRAY_SIZE(strtok_to_array(column2, ';')) as solution_3
FROM VALUES
('id01','Jon;karl;lee'),
('id02','Abi;jackson'),
('id03','don');
which gives
COLUMN1
COLUMN2
SOLUTION_1
SOLUTION_2
SOLUTION_3
id01
Jon;karl;lee
3
3
3
id02
Abi;jackson
2
2
2
id03
don
1
1
1
It depends on which DataBase you're using, because there are some different
things in syntax. I made your example with using SQLite Browser and I have a result like this one:
SELECT SUM(length(names) - length(replace(names, ';', '')) +1)
AS TotalCount
FROM Lee_tab where id = USER ID
As I know, in Postgres there's no length, it's just len there, so, pay an attention.
My query-it's just a formula to how count values, separated by ;
To get your result, you should learn how to join.
Here is a different answer, using the Snowflake SPLIT_TO_TABLE function. This function splits the string on the delimiter, creating a row for each value, which we lateral join back to the CTE table, finally we COUNT and GROUP BY using standard SQL syntax:
with cte as (
select 'id01' as user, 'Jon;karl;lee' as names union all
select 'id02' as user, 'Abi;jackson' as names union all
select 'id03' as user, 'don' as names
)
select user, names, count(value) as count_names
from cte, lateral split_to_table(cte.names, ';')
group by user, names;
Rewriting json_stattham's answer using Snowflake syntax. Basically, we are just counting the number of separators (semicolons) in the string and adding 1. There is no need to use the SUM() function as in json_stattham's answer.
with cte as (
select 'id01' as user, 'Jon;karl;lee' as names union all
select 'id02' as user, 'Abi;jackson' as names union all
select 'id03' as user, 'don' as names
)
SELECT user, names, (length(names) - length(replace(names, ';'))) + 1 AS name_count
FROM cte;
This is the answer for your query
select user,names,(len(names) - len(replace(names, ';',''))+1) names_count from Lee_tab;
for more understanding check this ,i have done all
https://www.db-fiddle.com/f/BQuEjw2pthMDb1z8NTdHv/0

Query to get number of % sign = length of string in the next row in Oracle 10g

is there any SQL query in Oracle10G which can give the desired output as given required in below sample.
Query should print the name first and in the second row it should print the "%" equal in number with the length of the string.
Could you please help?
Below is the sample of table column
JIM
JOHN
MICHAEL
and the output should come like below :
JIM
%%%
JOHN
%%%%
MICHAEL
%%%%%%%
This would normally be considered an issue for presentation logic, not database logic. However, one option would be to use union all, and then length and rpad to get the correct number of % signs. You'd also need to establish a row number to keep the order together.
Here's one approach:
select name
from (
select name, rownum rn
from yourtable
union all
select rpad('%', length(name), '%') name, rownum + 1 rn
from yourtable ) t
order by rn, name
SQL Fiddle Demo
you can check this link
http://www.club-oracle.com/articles/oracle-pivoting-row-to-column-conversion-techniques-sql-166/
there are many options discussed, it will help

SQL SELECT group multiple rows together when LISTAGG and WM_CONCAT are not available [duplicate]

This question already has answers here:
SQL Query to concatenate column values from multiple rows in Oracle
(10 answers)
Closed 8 years ago.
I'm having trouble explaining this, so if someone can make adjustments to the title or question then please do.
I have a simple SQL query that I'm running
SELECT orders.customer_no, orders.order_no FROM orders WHERE orders.creation = '01-JAN-14';
resulting in
customer_no order_no
----------- ----------
0 8051729
2 2809137
2 3794827
3 1934678
3 9237192
6 3462890
6 3131378
6 6267190
6 2864952
6 1325645
but what I want is
customer_no order_no
----------- ----------
0 8051729
2 2809137 3794827
3 1934678 9237192
6 3462890 3131378 6267190 2864952 1325645
Is it possible to do something like this direct within SQL?
Edit: Using Oracle8i Enterprise Edition Release 8.1.7.4.0 - Production.
I believe you want:
select orders.customer_no, listagg(orders.order_no, ' ') within group (order by orders.order_no) orders.order_no
from orders
WHERE orders.creation = '01-JAN-14'
group by orders.customer_no;
In MySQL you would want the GROUP_CONCAT function, which is roughly LISTAGG in Oracle, according to:
Is there any function in oracle similar to group_concat in mysql?
Based on Oracle: Way to aggregate concatenate an ungrouped column in grouped results, you can try something like:
WITH j
AS (SELECT customer_no, order_no
FROM orders
WHERE creation = '01-JAN-14')
SELECT RTRIM (
EXTRACT (SYS_XMLAGG (XMLELEMENT ("X", order_no || ' ')), '/ROWSET/X/text()').getstringval (),
', ')
FROM j
GROUP BY customer_no;

Make a query to split a line into x line depending on a field

I got a line in my data base, containing a fields with some names, separated by a ; .
I am trying to get, with a Select query, as many lines, that there is name in my field.
So, if I got in my DB :
id names
1 john;jack;mike
With this, i must get with this query :
SELECT id, split(names, ';') from table
1 john
1 jack
1 mike
I don't have any other table, so no join.
I write : split(names, ';'), but this is just an example of what I want to do.
But I don't know how to split my field names to do it like ahead.
I don't found any thing to help me, find a way to do it.
Do I need to use a function? Is there a function to do so with oracle?
Thank you.
SELECT id, TRIM(REGEXP_SUBSTR( names, '[^;]+', 1, LEVEL)) FROM table_name
CONNECT BY LEVEL <= LENGTH(REGEXP_REPLACE(names, '[^;]+')) + 1
AND PRIOR id = id
AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL
SQL Fiddle

grouping items in sql query

I have a table with columns like (in sql server 2000)
MailCode Mode Name Group
-------- ----- --------- -------
1 1 abc 0
1 1 def 0
1 1 qwe 1
2 2 aaw 0
2 2 aad 0
I want to group the Name field based on the rest of the fileds so that the result looks like this (there should be only one unique mailCode, Mode and group combination)
MailCode Mode Names Group
--------- ------ ------------ -------
1 1 abc, def 0
1 1 qwe 1
2 2 aaw, aad 0
How can I create the sql query for this?
I had a similar problem where I had to concatenate a field in the select, my solution at the time was to create a procedure that returned the result and called it like this
select x as field1, y as field2, dbo.procedure as field3
SQL Server 2000 solution
Luckily, COALESCE is supported in 2000, so you can use the COALESCE trick to create a comma delimited list of values, demonstrated in this link. Because of the variable usage, you'll need to create a function/procedure and call it within the main query. Basically, just replace the STUFF() in the query below with the function call.
SQL Server 2005+ solution:
SELECT x.mailcode,
x.mode,
STUFF((SELECT y.name
FROM TABLE y
WHERE y.mailcode = x.mailcode
AND y.mode = x.mode
AND y.gropu = x.group
GROUP BY y.mailcode, y.mode, y.group
FOR XML PATH(', ')), 1, 1, '') AS name,
x.group
FROM TABLE x
GROUP BY x.mailcode, x.mode, x.group
I can't think of a simple query that will get the result you're looking for, but some logic along these lines should get you where you want:
1) Loop through distinct MailCode, Mode, Group Rows
A) select all names in group
A.1) Loop through names
A.2) Concatenate them together into temp variable
B) insert all data (MailCode, Mode, Group, temp variable) into temp table
Fair waring, looping in SQL tends to have a huge performance hit when it comes to large datasets. I unfortunately don't know a better way to do it.