concatenate results of a sql query - sql

I am trying to figure if it is possible to concatenate the results of a SQL query if the output has more than one value
For example: If the below query returns more than one result
select * from employee
Output:
emp1
emp2
emp3
I want the results to show as
emp1, emp2, emp3

You can use "listagg"
Example:
SELECT LISTAGG(columnname, ',') WITHIN GROUP (ORDER BY columname)
Hope it resolves the issue!

SELECT LISTAGG(empname,',') WITHIN GROUP(ORDER BY empname) FROM emp;

You can use the listagg function
select listagg(first_name,',') within group(order by employee_id) from employees;
I am using the employees table of HR schema provided in oracle 11g release 2.

You can use the xmlelement function.
SELECT
RTRIM (XMLAGG (XMLELEMENT (E, EMPLOYEENAME|| ', ')).EXTRACT ('//text()'), ',') ENAMES
FROM
EMPLOYEE;

Related

How can I replace this listagg function to xmlagg

I want to replace the below query using XMLAGG function and also eliminate the distinct logic.
SELECT
listagg(distinct OD.PROD_NAME,';') within group(order by SC.CATEGORY_ID) as PRODUCT
FROM
orders OD,
SERVICES SC
I tried to refer below query but couldn't understand
select
deptno,
rtrim (xmlagg (xmlelement (e, ename || ',')).extract ('//text()'), ',') enames
from
emp
group by
deptno
;
You tagged the question with "Oracle 11g" tag; it doesn't support LISTAGG (DISTINCT ...) - distinct was introduced in 19c so - if you aren't on that version (or higher), you can't use it.
What to do, then? Use a subquery to fetch distinct values you need, and the join it (the subquery) to another table.
Here's an example based on Scott's sample schema (as I don't have your tables):
SQL> SELECT LISTAGG (e.job, ';') WITHIN GROUP (ORDER BY d.deptno, e.job) result
2 FROM (SELECT DISTINCT deptno, job
3 FROM emp) e
4 JOIN dept d ON d.deptno = e.deptno;
RESULT
------------------------------------------------------------------------------------------------------------------------
CLERK;MANAGER;PRESIDENT;ANALYST;CLERK;MANAGER;CLERK;MANAGER;SALESMAN
SQL>
SQL>
SQL> SELECT RTRIM (
2 XMLAGG (XMLELEMENT (e, e.job || ';') ORDER BY d.deptno, e.job).EXTRACT (
3 '//text()'),
4 ';') result
5 FROM (SELECT DISTINCT deptno, job
6 FROM emp) e
7 JOIN dept d ON d.deptno = e.deptno;
RESULT
------------------------------------------------------------------------------------------------------------------------
CLERK;MANAGER;PRESIDENT;ANALYST;CLERK;MANAGER;CLERK;MANAGER;SALESMAN
SQL>
Or, one below another (for better visibility):
LISTAGG: CLERK;MANAGER;PRESIDENT;ANALYST;CLERK;MANAGER;CLERK;MANAGER;SALESMAN
XMLAGG : CLERK;MANAGER;PRESIDENT;ANALYST;CLERK;MANAGER;CLERK;MANAGER;SALESMAN
As you can see, both return the same result.
Can I suggest a query for your case? Nope; as I said, I don't have your tables and I have no idea how orders and services are related to each other.

SQL Group by, but allow duplicate if value is the same

I'm trying to group some max values by an ID (until here i got it figured out), and I also need to select the names from the persons with the max values, so my grouping should allow duplicates if two persons with that grouped ID have the same value (max).
Here's what I've got so far.
SELECT MGR,MAX(SAL) AS MaxSal
FROM EMP
WHERE MGR IS NOT NULL
GROUP BY MGR
Now I also need to extract the field ENAME, how could I do this, while grouping and also allowing duplicate groups when necessary ?
Starting Oracle 12c, one option uses window functions in the order by clause and a fetch clause:
select mgr, ename, sal
from emp
where mgr is not null
order by rank() over(partition by mgr order by sal desc)
fetch first row with ties
The solution is analytic functions. Here's how I achieved my desired result.
SELECT MGR,ENAME,SAL
FROM
(
SELECT MGR,ENAME,SAL,
MAX(SAL) OVER (PARTITION BY MGR) AS MaxSal
FROM EMP
)
WHERE SAL=MaxSal

Dynamic grouping and hirearchical results in sql

I need to produce Hierarchical summary in sql.
The user will send the columns to group by as parameters to the stored procedure ,so group by is dynamic
For eg. User will send to group records by DeptNo and then by Job columns
I need to produce the result as below
Final output
The individual query for group by deptno
Select d.DEPTNO,Count(EmpNo) EmpCount, Sum(Sal) Total from Emp e inner join Dept d
on e.DEPTNO=d.DEPTNO GROUP BY d.DEPTNO;
The query for group by DEPTNO,Job
select Deptno, Job, Count(EmpNo) EmpCount, Sum(Sal) Total from emp group by DEPTNO,Job order by deptno
DeptnobyJob
Currently the query i used to produce the result is as below
select Deptno, Job,
Count(EmpNo) EmpCount,
Sum(Sal) Total
from emp group by DEPTNO,Job with rollup order by Deptno, EmpCount desc
Is there any other better option to get summary results.
It is to display in mvc web and no ssrs
An alternate solution to GROUPING SETS and with Rollupis Dynamic SQL. Build up a query string and execute it using Execute. If anyone one wants to try, Do something like this:
declare #Query nvarchar(max) = 'select column1,column2,Column3, Count(*) from table1 group by ' + #param1 + ',' + #param2 + ',' + #param3;
Execute(#Query)
you can build a dynamic query according to your liking using your parmeters and then execute it to get the desired results. Be ware of SQL Injection Though!

Query without listagg function

Can someone help me to get desired output without using listagg function.
Requirement:
Write a query to get the job_id and related employee's id.
Output:
jobname Empno
AC_ACCOUNT 206
AC_MGR 205
AD_ASST 200
AD_PRES 100
AD_VP 101,102
FI_ACCOUNT 110 ,113 ,111 ,109 ,112
I have achieved using listagg function.
select jobname, listagg(empno, ',') within group (order by empno) empno
from emp group by jobname;
But I want to know if possible to write a query without using listagg fucntion?
Yes, it is possible.
You can use hierarchical query.
with sel as (
select job_id, employee_id
from employees
order by job_id, employee_id)
, sel2 as (
select rownum r, job_id, employee_id
from sel)
, sel3 as (
select sel2.*, ltrim(sys_connect_by_path (employee_id,','),',') res, level l
from sel2
connect by prior job_id=job_id and r=prior r+1
order by job_id)
select job_id, res
from sel3 s
where l = (select max(l) from sel3 where job_id=s.job_id);
No, unless you want to use PLSQL to achieve that. LISTAGG was created for that very reason, to achieve that output. Let oracle do the heavy stuff for you
Check out XMLAGG function. link

Trying to get the result in single row using sql? [duplicate]

This question already has answers here:
SQL Query to concatenate column values from multiple rows in Oracle
(10 answers)
Closed 1 year ago.
I'm trying to display all the employee id's
i need the result like
emp_id
10,11,12,13,14,15..,...
when tried
SELECT LISTAGG(emp_id, ',') WITHIN GROUP (ORDER BY emp_id) AS ID FROM employees GROUP BY emp_id;
I'm getting error
ORA-00923: FROM keyword not found where expected
where is the problem here?
Use LISTAGG function. Refer here for more in detail. Try like this,
SELECT listagg(emp_id,',') WITHIN GROUP(ORDER BY emp_id) t
FROM employees;
For SQL try
SELECT GROUP_CONCAT(emp_id) as emp_id FROM employees;
Working demo at http://sqlfiddle.com/#!2/90dd2/1
For Oracle
SELECT LISTAGG(emp_id,',') WITHIN GROUP(ORDER BY emp_id) as emp_id
FROM employees;
demo at http://sqlfiddle.com/#!4/af004/9
Try this
SELECT CONCAT(emp_id,',') FROM employees;
try this
declare #empid nvarchar(500)=''
select #empid=#empid+Emp_id + ',' from tblemployee
select substring(#empid,0,len(#empid)-1)
Try this:
SELECT GROUP_CONCAT(emp_id) as emp_id FROM employees;