Group by clause and having clause in select
hi frnds
plz give me some information of group by and having clause used in select statement with example
thanks
The Open SQL statement for reading data from database tables is:
SELECT <result>
INTO <target>
FROM <source>
[WHERE <condition>]
[GROUP BY <fields>]
[HAVING <cond>]
[ORDER BY <fields>].
The SELECT statement is divided into a series of simple clauses, each of which has a different part to play in selecting, placing, and arranging the data from the database.
You can only use the HAVING clause in conjunction with the GROUP BY clause.
To select line groups, use:
SELECT <lines> <s1> [AS <a1>] <s2> [AS <a2>] ...
<agg> <sm> [AS <am>] <agg> <sn> [AS <an>] ...
GROUP BY <s1> <s2> ....
HAVING <cond>.
The conditions <cond> that you can use in the HAVING clause are the same as those in the SELECT clause, with the restrictions that you can only use columns from the SELECT clause, and not all of the columns from the database tables in the FROM clause. If you use an invalid column, a runtime error results.
On the other hand, you can enter aggregate expressions for all columns read from the database table that do not appear in the GROUP BY clause. This means that you can use aggregate expressions, even if they do not appear in the SELECT clause. You cannot use aggregate expressions in the conditions in the WHERE clause.
As in the WHERE clause, you can specify the conditions in the HAVING clause as the contents of an internal table with line type C and length 72.
Example
DATA WA TYPE SFLIGHT.
SELECT CONNID
INTO WA-CONNID
FROM SFLIGHT
WHERE CARRID = 'LH'
GROUP BY CONNID
HAVING SUM( SEATSOCC ) > 300.
WRITE: / WA-CARRID, WA-CONNID.
ENDSELECT.
This example selects groups of lines from database table SFLIGHT with the value LH for CARRID and identical values of CONNID. The groups are then restricted further by the condition that the sum of the contents of the column SEATSOCC for a group must be greater than 300.
The <b>GROUP BY</b> clause summarizes several lines from the database table into a single line of the selection.
The GROUP BY clause allows you to summarize lines that have the same content in particular columns. Aggregate functions are applied to the other columns. You can specify the columns in the GROUP BY clause either statically or dynamically.
Specifying Columns Statically
To specify the columns in the GROUP BY clause statically, use:
SELECT <lines> <s1> [AS <a 1>] <s 2> [AS <a 2>] ...
<agg> <sm> [AS <a m>] <agg> <s n> [AS <a n>] ...
GROUP BY <s1> <s 2> ....
To use the GROUP BY clause, you must specify all of the relevant columns in the SELECT clause. In the GROUP BY clause, you list the field names of the columns whose contents must be the same. You can only use the field names as they appear in the database table. Alias names from the SELECT clause are not allowed.
All columns of the SELECT clause that are not listed in the GROUP BY clause must be included in aggregate functions. This defines how the contents of these columns is calculated when the lines are summarized.
Specifying Columns Dynamically
To specify the columns in the GROUP BY clause dynamically, use:
... GROUP BY (<itab>) ...
where <itab> is an internal table with line type C and maximum length 72 characters containing the column names <s 1 > <s 2 > .....
Example
DATA: CARRID TYPE SFLIGHT-CARRID,
MINIMUM TYPE P DECIMALS 2,
MAXIMUM TYPE P DECIMALS 2.
SELECT CARRID MIN( PRICE ) MAX( PRICE )
INTO (CARRID, MINIMUM, MAXIMUM)
FROM SFLIGHT
GROUP BY CARRID.
WRITE: / CARRID, MINIMUM, MAXIMUM.
ENDSELECT.
regards
vinod
Similar Messages
-
-- SQL -- GROUP BY clause: non-aggregate fields mandate
Hello,
I was studying Databases, (particularly the retrieval of the data), and found something interesting.
While using an Aggregate Function in the SELECT clause, it is mandatory to have all the non-aggregate fields in the SELECT clause to be there in the GROUP BY clause.
For example,
SELECT dept_no, SUM(salary)
FROM employee
GROUP BY dept_no;
The above SQL works fine.
But, what if the user misses the dept_no in the GROUP BY clause or he/she misses the GROUP BY clause itself?
Certainly, it is an error.
Why is this error not handled by the database. I mean, the database should be smart/intelligent enough to add the GROUP BY clause by itself. So suppose, if I miss out the GROUP BY clause or miss a non-aggregate field from the SELECT clause when I am having at least one aggregate function on a field with at least one non-aggregated field in the SELECT clause, the database should check the GROUP BY clause at time of compilation and add the mandate missed out fields in the GROUP BY clause.
Example,
SQL1:_
SELECT dept_no, SUM(salary)
FROM employee
GROUP BY dept_no;
SQL2:_
SELECT dept_no, SUM(salary)
FROM employee;
Here, the SQL1 and SQL2, both should give me same outputs without an error.
I am unable to understand why is this not handled?Hi,
998478 wrote:
... If we mix aggregate and non-aggregate values then there must be a GROUP BY clause containing all the non-aggregate values. Why is this not handled by the database/compiler itself? It IS handled by the compiler itself. The compiler handles it by raising an error. The compiler has no way of knowing whether you want to remove something from the SELECT clause, or to add something to the GROUP BY clause, or not to use aggregate functions, or to use more aggregate functions, or some combination of the above. If the compiler re-wrote your code, and did any of these things automatically, it would be wrong more often than it was right, and you would (rightly) be complaining about its behavior.
For example, this is clearly wrong:
SELECT deptno
, job
, SUM (sal)
FROM scott.emp
GROUP BY deptno
;What is the right way to fix it?
<h3>1. Remove something from the SELECT clause</h3>
SELECT deptno
, SUM (sal)
FROM scott.emp
GROUP BY deptno
;<h3>2. Add something to the GROUP BY clause</h3>
SELECT deptno
, job
, SUM (sal)
FROM scott.emp
GROUP BY deptno
, job
;<h3>3. Not use aggregate functions</h3>
SELECT deptno
, job
, sal
FROM scott.emp
;<h3>4. Use more aggregate functions</h3>
SELECT deptno
, MIN (job)
, SUM (sal)
FROM scott.emp
GROUP BY deptno
;These aren't all the options, either. For example, the correct fix might be to use analytic functions instead of aggregate functions.
How can anybody say which of these is right? All of them are the right answer for some problem.
By the way, saying that everying in the SELECT clause must be an aggregate or in the GROUP BY clause is a bit over-simplified.
More completely, here are the ABC's of GROUP BY:
When you use a GROUP BY clause and/or an aggregate function, then everything in the SELECT clause must be:
(A) an <b>A</b>ggregate function,
(B) one of the "group <b>B</b>y" expressions,
(C) a <b>C</b>onstant, or
(D) something that <b>D</b>epends entirely on the above. (For example, if you "GROUP BY TRUNC(dt)", you can SELECT "TO_CHAR (TRUNC(dt), 'Mon-DD')").
Edited by: Frank Kulash on Apr 13, 2013 1:44 PM
Added code examples. -
Aggregate fuction with group by clause
Hello,
Following is assignment is given but i dont get correct output
so please i am request to all of us write code to solve my problem.
There can be multiple records for one customer in VBAK tables with different combinations.
Considering that we do not need details of each sales order,
use Aggregate functions with GROUP BY clause in SELECT to read the fields.
<garbled code removed>
Moderator Message: Please paste the relevant portions of the code
Edited by: Suhas Saha on Nov 18, 2011 1:48 PMSo if you need not want all the repeated records, then you select all the values to an Internal table,
and declare an internal table of same type and Usee COLLECT
for ex:
itab1 type <xxxx>.
wa_itba like line of itab1.
itab2 type <xxxx>. "<-This should be same type of above.
select * from ..... into table itab1.
and now...
loop at itab1 into wa_itab.
collect wa_itab1 into itab2.
endloop.
then you will get your desired result.. -
Hello All,
I need to print amount due for each customer when it is negative (less than zero). i.e. sum of all transactions against the customer should be less than zero. This is simple through sql if we write "select sum(amount) group by customer having sum(amount) < 0".
But I need to do this in discoverer. Now the issue is I need to pass two parameters at runtime. First one will be Date (<= as_of_date) and another one will be having multiple values (in clause).
If I base my report on underlying report view which uses 'group by... having' sql as described above, I will have to use parameter sheet and use syscontext to pass parameters.
Instead, it will be easier if i pull in all the data in discoverer report and then use parameters to filter it out. But then is there any way to group on customer and having clause to print only those customers where sum(amount) < 0?
AnishHi Russ,
I am new to discoverer so pardon me if I am not able to get you quickly.
I am sorry, but I did not get you when you say calc1 = SUM( CASE WHEN amount <0 then amount ELSE 0 END).
May be I was not able to describe you problem. Below is the SQL statement that will give me desired results. I want to achieve same results in Discoverer by getting rid of outer select query with grouping. I will be passing org_id and GL date as parameters.
select customer_number, name, sum(amount_due) Amount_Due, org_id, Business_Segment
from
SELECT hca.account_number customer_number, hp.party_name NAME,
aps.trx_number, aps.gl_date,
aps.amount_due_remaining amount_due, aps.class, aps.org_id org_id
,hca.attribute3
FROM apps.ar_payment_schedules_all aps,
apps.hz_cust_accounts hca,
apps.hz_parties hp
WHERE aps.org_id IN (570, 573)
AND aps.gl_date <= '30-NOV-2008'
AND aps.class in ('CM','INV','DM')
AND aps.customer_id = hca.cust_account_id
AND hca.party_id = hp.party_id
group by customer_number, name,org_id, Business_Segment
having sum(amount_due) < 0
order by 1
Hope I am able to explain you now.
Thanks,
Anish -
Count(*) in select statement having group by clause
Hi
I would like to use count(*) in select statement having group by clause. say for example there is a state with a number of cities listed. I would like to get the count of cities for each state.
the sql stement is grouped by city and it is joined with 5 more tables.
ThanksI suspect you want to look into analytic functions (assuming you have a recent version of Oracle). asktom.oracle.com has numerous examples if you do a search.
Justin -
Use of group by and having clause
hi frnds
can anybody explain me the use of group by an having clause in select state mentHi Rohit,
1. GROUP BY f1 ... fn
2. GROUP BY (itab)
1. GROUP BY f1 ... fn
Effect
Groups database table data in a SELECT command on one line in the result set. A group is a set of lines which all have the same values in each column determined by the field descriptors f1 ... fn.
... GROUP BY f1 ... fn always requires a list in the SELECT clause. If you use field descriptors without an aggregate funciton in the SELECT clause, you must list them in the GROUP BY f1 ... fn clause.
Example
Output the number of passengers, the total weight and the average weight of luggage for all Lufthansa flights on 28.02.1995:
TABLES SBOOK.
DATA: COUNT TYPE I, SUM TYPE P DECIMALS 2, AVG TYPE F.
DATA: CONNID LIKE SBOOK-CONNID.
SELECT CONNID COUNT( * ) SUM( LUGGWEIGHT ) AVG( LUGGWEIGHT )
INTO (CONNID, COUNT, SUM, AVG)
FROM SBOOK
WHERE
CARRID = 'LH' AND
FLDATE = '19950228'
GROUP BY CONNID.
WRITE: / CONNID, COUNT, SUM, AVG.
ENDSELECT.
Note
... GROUP BY f1 ... fn is not supported for pooled and cluster tables.
2. GROUP BY (itab)
Effect
Works like GROUP BY f1 ... fn if the internal table itab contains the list f1 ... fn as ABAP source code. The internal table itab can only have one field. This field must be of the type C and should not be more than 72 characters long. itab must be enclosed in parentheses and there should be no blanks between the parentheses and the table name.
Note
The same restrictions apply to this variant as to GROUP BY f1 ... fn.
Example
Output all Lufthansa departure points with the number of destinations:
TABLES: SPFLI.
DATA: BEGIN OF WA.
INCLUDE STRUCTURE SPFLI.
DATA: COUNT TYPE I.
DATA: END OF WA.
DATA: WA_TAB(72) TYPE C,
GTAB LIKE TABLE OF WA_TAB,
FTAB LIKE TABLE OF WA_TAB,
COUNT TYPE I.
CLEAR: GTAB, FTAB.
WA_TAB = 'COTYFROM COUNT( * ) AS COUNT'. APPEND FTAB.
APPEND WA_TAB TO FTAB.
WA_TAB = 'CITYFROM'.
APPEND WA_TAB TO GTAB.
SELECT DISTINCT (FTAB)
INTO CORRESPONDING FIELDS OF WA
FROM SPFLI
WHERE
CARRID = 'LH'
GROUP BY (GTAB).
WRITE: / WA-CITYFROM, WA-COUNT.
ENDSELECT.
Regards,
Susmitha -
Creation of view with clob column in select and group by clause.
Hi,
We are trying to migrate a view from sql server2005 to oracle 10g. It has clob column which is used in group by clause. How can the same be achived in oracle 10g.
Below is the sql statament used in creating view aling with its datatypes.
CREATE OR REPLACE FORCE VIEW "TEST" ("CONTENT_ID", "TITLE", "KEYWORDS", "CONTENT", "ISPOPUP", "CREATED", "SEARCHSTARTDATE", "SEARCHENDDATE", "HITS", "TYPE", "CREATEDBY", "UPDATED", "ISDISPLAYED", "UPDATEDBY", "AVERAGERATING", "VOTES") AS
SELECT content_ec.content_id,
content_ec.title,
content_ec.keywords,
content_ec.content content ,
content_ec.ispopup,
content_ec.created,
content_ec.searchstartdate,
content_ec.searchenddate,
COUNT(contenttracker_ec.contenttracker_id) hits,
contenttypes_ec.type,
users_ec_1.username createdby,
Backup_Latest.created updated,
Backup_Latest.isdisplayed,
users_ec_1.username updatedby,
guideratings.averagerating,
guideratings.votes
FROM users_ec users_ec_1
JOIN Backup_Latest
ON users_ec_1.USER_ID = Backup_Latest.USER_ID
RIGHT JOIN content_ec
JOIN contenttypes_ec
ON content_ec.contenttype_id = contenttypes_ec.contenttype_id
ON Backup_Latest.content_id = content_ec.content_id
LEFT JOIN guideratings
ON content_ec.content_id = guideratings.content_id
LEFT JOIN contenttracker_ec
ON content_ec.content_id = contenttracker_ec.content_id
LEFT JOIN users_ec users_ec_2
ON content_ec.user_id = users_ec_2.USER_ID
GROUP BY content_ec.content_id,
content_ec.title,
content_ec.keywords,
to_char(content_ec.content) ,
content_ec.ispopup,
content_ec.created,
content_ec.searchstartdate,
content_ec.searchenddate,
contenttypes_ec.type,
users_ec_1.username,
Backup_Latest.created,
Backup_Latest.isdisplayed,
users_ec_1.username,
guideratings.averagerating,
guideratings.votes;
Column Name Data TYpe
CONTENT_ID NUMBER(10,0)
TITLE VARCHAR2(50)
KEYWORDS VARCHAR2(100)
CONTENT CLOB
ISPOPUP NUMBER(1,0)
CREATED TIMESTAMP(6)
SEARCHSTARTDATE TIMESTAMP(6)
SEARCHENDDATE TIMESTAMP(6)
HITS NUMBER
TYPE VARCHAR2(50)
CREATEDBY VARCHAR2(20)
UPDATED TIMESTAMP(6)
ISDISPLAYED NUMBER(1,0)
UPDATEDBY VARCHAR2(20)
AVERAGERATING NUMBER
VOTES NUMBERAny help realyy appreciated.
Thanks in advance
Edited by: user512743 on Dec 10, 2008 10:46 PMHello,
Specifically, this should be asked in the
ASP.Net MVC forum on forums.asp.net.
Karl
When you see answers and helpful posts, please click Vote As Helpful, Propose As Answer, and/or Mark As Answer.
My Blog: Unlock PowerShell
My Book: Windows PowerShell 2.0 Bible
My E-mail: -join ('6F6C646B61726C40686F746D61696C2E636F6D'-split'(?<=\G.{2})'|%{if($_){[char][int]"0x$_"}}) -
Use of Where and having clause
Hi all,
I always have a doubt about use of HAVING and WHERE clause,
suppose I have table T1 with only one column C1
CREATE TABLE T1
(C1 VARCHAR2(1) );
which having data by following INSERT scripts
INSERT INTO T1 VALUES('A');
INSERT INTO T1 VALUES('B');
INSERT INTO T1 VALUES('C');
INSERT INTO T1 VALUES('A');
INSERT INTO T1 VALUES('B');
INSERT INTO T1 VALUES('A');
Now I want result as follows
C1 ==== COUNT(C1)
==============
B ===== 2
A ===== 3
So out of query 1 and 2 which approach is right ?
1) SELECT C1,COUNT(C1) FROM T1
WHERE C1<>'C'
GROUP BY C1
ORDER BY C1 DESC;
2) SELECT C1,COUNT(C1) FROM T1
GROUP BY C1
HAVING C1<>'C'
ORDER BY C1 DESC;
Edited by: user13306874 on Jun 21, 2010 2:36 AMIn SQL, it's always best to filter data at the earliest moment possible.
In your example the WHERE clause would be that moment:
SQL> explain plan for
2 select c1,count(c1)
3 from t1
4 where c1 != 'C'
5 group by c1
6* order by c1 desc;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
Plan hash value: 3946799371
| Id | Operation | Name | Rows | Bytes |
| 0 | SELECT STATEMENT | | 5 | 10 |
| 1 | SORT GROUP BY | | 5 | 10 |
|* 2 | TABLE ACCESS FULL| T1 | 5 | 10 |
Predicate Information (identified by operation id):
2 - filter("C1"!='C')
18 rows selected.
SQL>As you can see the filter is applied during the scan of T1.
Whereas in the HAVING case:
SQL> explain plan for
2 select c1,count(c1)
3 from t1
4 group by c1
5 having c1 != 'C'
6* order by c1 desc;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
Plan hash value: 3146800528
| Id | Operation | Name | Rows | Bytes |
| 0 | SELECT STATEMENT | | 6 | 12 |
|* 1 | FILTER | | | |
| 2 | SORT GROUP BY | | 6 | 12 |
| 3 | TABLE ACCESS FULL| T1 | 6 | 12 |
Predicate Information (identified by operation id):
1 - filter("C1"!='C')
18 rows selected.
SQL>The scan is done after all groups have been computed: one of which was computed in vain, since it will be filtered away due to the HAVING clause.
In general I would use as a guideline: if you are not using aggregate functions in your HAVING clause predicate, then move that predicate to the WHERE portion of your query.
Edited by: Toon Koppelaars on Jun 21, 2010 11:54 AM -
Which two statements are true about WHERE and HAVING clause ?
Which two statements are true about WHERE and HAVING clause ?
1. WHERE clause can be used to restict rows only
2.HAVING clause can be used to restrict groups only
3.HAVING clause can be used to restrict groups and rows
Plz help me in dis ques...which two will be correct...i think its 1 and 2...but not sure.863180 wrote:
Plz help me in dis ques...which two will be correct...i think its 1 and 2...but not sure.If you are not sure then you do not fully understand HAVING.
SY. -
Passing where and group by clause to cursor
I am working on a procedure that builds a where clause and needs a group by clause to return the correct results. I am trying to pass both the where and group by variables into the cursor.
The variables are getting populated correctly, but when the cursor gets created, the variables are not in the cursor.
Here is the code I'm working with. It is a part of a package, but makes no calls to other parts of the package.
PROCEDURE createFollowUpTask_Exposure( psUppgkedjetyp IN tis.tial.uppgkedjetyp%TYPE default NULL,
psAlarmtyp IN tis.tial.alarmtyp%TYPE default NULL,
psSubtyp IN tis.tial.subtyp%TYPE default NULL,
pnDays IN NUMBER default NULL,
psKampkod IN tis.tiin.kampkod%TYPE default NULL,
psKatnr IN tis.tiin.katnr%TYPE default NULL,
psUtgava IN tis.tiin.utgava%TYPE default NULL,
psKatslag IN tis.tikg.katslag%TYPE default NULL,
psProdsyst IN tis.tikg.prodsyst%TYPE default NULL,
psUppgtyp IN tis.tiin.uppgtyp%TYPE default NULL,
psProdkod IN tis.tiin.prodkod%TYPE default NULL,
psStatus IN tis.tiin.status%TYPE default NULL
) AS
cTIAL tis.tial%ROWTYPE;
vLopnr tis.tial.lopnr%TYPE;
vSqlWhere VARCHAR2(4000);
vGroupBy VARCHAR2(1000) := ' tiin.kampkod, tiin.abnr, tiko.fordsalj';
cSelectCursor SYS_REFCURSOR;
vSqlSelect VARCHAR2(4000);
psDays VARCHAR2(50);
cRec T_TIAL_REC;
nCount number := 0;
CURSOR cSqlSelect( SqlWhere IN VARCHAR2, GroupBy IN VARCHAR2) IS
SELECT tiin.kampkod, tiin.abnr, tiko.fordsalj, MAX(tici.regdat) ALARMDATE
FROM tis.tiin
JOIN tis.tiko ON tiin.kampkod = tiko.kampkod AND tiin.abnr = tiko.abnr
JOIN core.tici ON tiin.kampkod = tici.kampkod AND tiin.abnr = tici.abnr AND tici.inplnr = tiin.inplnr
WHERE 1=1 || SqlWhere
GROUP BY GroupBy;
BEGIN
-- If these parameters are null, raise error
IF psUppgkedjetyp IS NULL and psSubtyp IS NULL THEN
raise_application_error(-20001,
'Either Event Chain or Starting Event must be assigned');
END IF;
-- Populate TIAL values
IF psUppgkedjetyp IS NOT NULL THEN
cTIAL.Uppgkedjetyp := psUppgkedjetyp;
END IF;
IF psAlarmtyp IS NOT NULL THEN
cTIAL.Alarmtyp := psAlarmtyp;
END IF;
cTIAL.Handklass := 'T';
cTIAL.Blobid := 0;
IF pnDays IS NOT NULL THEN
psDays := '+ '||pnDays;
END IF;
IF psSubtyp IS NOT NULL THEN
cTIAL.Subtyp := psSubtyp;
END IF;
-- Create Where clause for cursor
vSqlWhere := '';
IF psKampkod IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tiin.kampkod = '''|| psKampkod||'''';
END IF;
IF psKatnr IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tiin.katnr = '''||psKatnr||'''';
END IF;
IF psUtgava IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tiin.utgava = '''||psUtgava||'''' ;
END IF;
IF psKatslag IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tikg.katslag = '''||psKatslag||'''';
END IF;
IF psProdsyst IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tikg.prodsyst = '''||psProdsyst||'''';
END IF;
IF psUppgtyp IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tiin.uppgtyp = '''||psUppgtyp||'''';
END IF;
IF psProdkod IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tiin.prodkod = '''||psProdkod||'''';
END IF;
IF psStatus IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tiin.status = '''||psStatus||'''';
END IF;
-- Loop through all records meeting input parameters and set required TIAL values.
FOR i IN cSqlSelect(vSqlWhere, vGroupBy)
LOOP
--FETCH cSelectCursor INTO cRec;
cTIAL.Kampkod := '';
cTIAL.Abnr := '';
cTIAL.Sign := '';
cTIAL.Alarmdate := '';
cTIAL.Kampkod := i.Kampkod;
cTIAL.Abnr := i.Abnr;
cTIAL.Sign := i.fordsalj;
cTIAL.Alarmdate := i.alarmdate;
nCount := nCount + 1;
IF vLopnr = -1 THEN
raise_application_error(-20002,
'Error Creating task for: '||cTIAL.Kampkod||' '||cTIAL.Abnr||' Sales Rep: '||cTIAL.Alarmdate);
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE('I created '||nCount||' records.');
END createFollowUpTask_Exposure;
Thanks in advance for any help.Hi,
Welcome to the forum!
Try this (not tested) as an example:
PROCEDURE createFollowUpTask_Exposure(psUppgkedjetyp IN tis.tial.uppgkedjetyp%TYPE DEFAULT NULL,
psAlarmtyp IN tis.tial.alarmtyp%TYPE DEFAULT NULL,
psSubtyp IN tis.tial.subtyp%TYPE DEFAULT NULL,
pnDays IN NUMBER DEFAULT NULL,
psKampkod IN tis.tiin.kampkod%TYPE DEFAULT NULL,
psKatnr IN tis.tiin.katnr%TYPE DEFAULT NULL,
psUtgava IN tis.tiin.utgava%TYPE DEFAULT NULL,
psKatslag IN tis.tikg.katslag%TYPE DEFAULT NULL,
psProdsyst IN tis.tikg.prodsyst%TYPE DEFAULT NULL,
psUppgtyp IN tis.tiin.uppgtyp%TYPE DEFAULT NULL,
psProdkod IN tis.tiin.prodkod%TYPE DEFAULT NULL,
psStatus IN tis.tiin.status%TYPE DEFAULT NULL) AS
cTIAL tis.tial%ROWTYPE;
vLopnr tis.tial.lopnr%TYPE;
vSqlWhere VARCHAR2(4000);
vGroupBy VARCHAR2(1000) := ' tiin.kampkod, tiin.abnr, tiko.fordsalj';
cSelectCursor SYS_REFCURSOR;
vSqlSelect VARCHAR2(4000);
psDays VARCHAR2(50);
cRec T_TIAL_REC;
nCount NUMBER := 0;
FUNCTION fnc_cSqlSelect(SqlWhere IN VARCHAR2,
GroupBy IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN
RETURN 'SELECT tiin.kampkod,
tiin.abnr,
tiko.fordsalj,
MAX(tici.regdat) ALARMDATE
FROM tis.tiin
JOIN tis.tiko ON tiin.kampkod = tiko.kampkod
AND tiin.abnr = tiko.abnr
JOIN core.tici ON tiin.kampkod = tici.kampkod
AND tiin.abnr = tici.abnr
AND tici.inplnr = tiin.inplnr
WHERE 1 = 1 ' || SqlWhere || ' GROUP BY ' || GroupBy;
END fnc_cSqlSelect;
BEGIN
-- If these parameters are null, raise error
IF psUppgkedjetyp IS NULL AND psSubtyp IS NULL THEN
raise_application_error(-20001,
'Either Event Chain or Starting Event must be assigned');
END IF;
-- Populate TIAL values
IF psUppgkedjetyp IS NOT NULL THEN
cTIAL.Uppgkedjetyp := psUppgkedjetyp;
END IF;
IF psAlarmtyp IS NOT NULL THEN
cTIAL.Alarmtyp := psAlarmtyp;
END IF;
cTIAL.Handklass := 'T';
cTIAL.Blobid := 0;
IF pnDays IS NOT NULL THEN
psDays := '+ ' || pnDays;
END IF;
IF psSubtyp IS NOT NULL THEN
cTIAL.Subtyp := psSubtyp;
END IF;
-- Create Where clause for cursor
vSqlWhere := '';
IF psKampkod IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tiin.kampkod = ''' || psKampkod || '''';
END IF;
IF psKatnr IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tiin.katnr = ''' || psKatnr || '''';
END IF;
IF psUtgava IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tiin.utgava = ''' || psUtgava || '''';
END IF;
IF psKatslag IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tikg.katslag = ''' || psKatslag || '''';
END IF;
IF psProdsyst IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tikg.prodsyst = ''' || psProdsyst || '''';
END IF;
IF psUppgtyp IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tiin.uppgtyp = ''' || psUppgtyp || '''';
END IF;
IF psProdkod IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tiin.prodkod = ''' || psProdkod || '''';
END IF;
IF psStatus IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tiin.status = ''' || psStatus || '''';
END IF;ç
-- Loop through all records meeting input parameters and set required TIAL values.
OPEN cSelectCursor FOR fnc_cSqlSelect(vSqlWhere,
vGroupBy);
LOOP
FETCH cSelectCursor
INTO v; -- You must define a variable 'v' to hold the data of cursor
EXIT WHEN cSelectCursor%NOTFOUND;
--FETCH cSelectCursor INTO cRec;
cTIAL.Kampkod := '';
cTIAL.Abnr := '';
cTIAL.Sign := '';
cTIAL.Alarmdate := '';
cTIAL.Kampkod := i.Kampkod;
cTIAL.Abnr := i.Abnr;
cTIAL.Sign := i.fordsalj;
cTIAL.Alarmdate := i.alarmdate;
nCount := nCount + 1;
IF vLopnr = -1 THEN
raise_application_error(-20002,
'Error Creating task for: ' || cTIAL.Kampkod || ' ' ||
cTIAL.Abnr || ' Sales Rep: ' || cTIAL.Alarmdate);
END IF;
END LOOP;
CLOSE cSelectCursor;
DBMS_OUTPUT.PUT_LINE('I created ' || nCount || ' records.');
END createFollowUpTask_Exposure;
/Regards, -
GROUP BY clause diff in Sybase and Oracle
Hi,
I am migrating code from Sybase to Oracle and came across a strange issue which is widely known to others :)
In Sybase , one can use columns or calculations in the SELECT expressions that don't appear
in the GROUP BY clause of the query. Like
SELECT order.custid,customer.name,MAX(payments)
-> FROM order, customer
-> WHERE order.custid = customer.custid
-> GROUP BY order.custid;
works fine but for SQL we need to add customer.name to GROUP BY clause.
On the similar lines, here is my SQL query
INSERT INTO GTT_CTRT_recalc_proc
(id_fin_rec,
id_imnt,
id_instr_opn,
dt_instr_opn,
dt_opn,
dt_cls_loanet,
dt_prcss,
am_invst)
SELECT t1.id_fin_rec,
t1.id_imnt,
t1.id_instr_opn,
t1.dt_instr_opn,
t1.dt_opn,
NVL(t1.dt_cls_loanet, l_dt_to),
t1.dt_prcss,
SUM(t2.am_invst) + (0.123 * (1 - abs(sign(0 - SUM(t2.am_invst)))))
FROM GTT_CTRT_TEMP_recalc_process t1, GTT_CTRT_TEMP_recalc_process t2
WHERE t2.id <= t1.id
AND t2.id_imnt = t1.id_imnt
AND t2.id_instr_opn = t1.id_instr_opn
AND t2.dt_instr_opn = t1.dt_instr_opn
GROUP BY t1.id_imnt,
t1.id_instr_opn,
t1.dt_instr_opn,
t1.dt_opn,
t1.dt_cls_loanet,
t1.dt_prcss;
Which does not have t1.id_fin_rec in GROUP BY failing it in SQL.
I know that if I add this column in GROUP BY it will work fine but I am told to keep the functionality as it is as the result before and after adding the column would be diff of-course.
Please guide me about what can be done in this situation and is there any work around for this?
Thanks,
AashishThat's a piece of nasty denormalisation. We shoudl also expect trouble we do stuff like that. Anyway, I think encapsulating the stuff from T2 into an inline view should sort you out....
INSERT INTO GTT_CTRT_recalc_proc
(id_fin_rec,
id_imnt,
id_instr_opn,
dt_instr_opn,
dt_opn,
dt_cls_loanet,
dt_prcss,
am_invst)
SELECT t1.id_fin_rec,
t1.id_imnt,
t1.id_instr_opn,
t1.dt_instr_opn,
t1.dt_opn,
NVL(t1.dt_cls_loanet, l_dt_to),
t1.dt_prcss,
, t2.total
FROM GTT_CTRT_TEMP_recalc_process t1
, ( select id_imnt,
id_instr_opn,
dt_instr_opn,
SUM(am_invst) + (0.123 * (1 - abs(sign(0 - SUM(am_invst))))) AS total
FROM GTT_CTRT_TEMP_recalc_process
GROUP BY id_imnt,
id_instr_opn,
dt_instr_opn ) t2
WHERE t2.id <= t1.id
AND t2.id_imnt = t1.id_imnt
AND t2.id_instr_opn = t1.id_instr_opn
AND t2.dt_instr_opn = t1.dt_instr_opn
GROUP BY t1.id_imnt,
t1.id_instr_opn,
t1.dt_instr_opn,
t1.dt_opn,
t1.dt_cls_loanet,
t1.dt_prcss;Cheers, APC
blog: http://radiofreetooting.blogspot.com
Edited by: APC on Mar 16, 2009 2:31 PM
Forgot to include GROUP BY in the inline view -
Select columns not in group by clause
Hi Guys,
I want to fetch columns from a table which are not in group by clause. The catch here is that I also need a count and decode column..
SELECT col_A, col_B, decode(col_C, '10', '10', '26', '26', '00') col_CT, col_X, col_Y count(*) CNT
FROM TABLE_T
WHERE col_B IN (100,101,102) AND col_C IN ('44','45','10','26')
GROUP BY col_A, col_B, decode(col_C, '10', '10', '26', '26', '00')
ORDER BY col_CT
Since, col_X and col_Y are not in GROUP BY clause, it throws error. Also, decode/count of the columns makes it more complex.
Please help me on this.
Thanks,
AmyHi, Amy,
Welcome to the forum!
Whenever you have a problem, post a little sample data (CREATE TABLE and INSERT statments, relevant columns only) for all tables involved, and the results you want from that data.
Always say which versionof Oracle you're using.
How to do what youy want depends on what you want, which is unclear.
If you say "GROUP BY a, b, c", that means you only want one row of output for each distinct combination of a, b and c. How do x and y fit into that? Do you want a separate output row for each distinct combination of a, b,c, x and y? Then add x and y to the GROUP BY clause. If you don't want separate rows for each combinataion of x and y, what do you want when a group has more than 1 value for either of them?
You can simplify the code a little by doing the DECODE in a sub-query; then you can use the alias col_ct as many times as you like in the main query. That will make the code easier to maintain, too. -
How to use order by within Group by clause
Hi All,
I need a help as to how should i use the Order by clause so that the data should be in order with respect to one column, and at the same time whole data is grouped by some other column...like
Select RaceNo,Venue,FP,BP from Race group by RaceNo
Here I want to order by FP in ascending order for each group. When i am using it , whole order is changing.
Can anybody suggest me how to use order by clause that would apply to each group of data.
Thanks .order by clause should be used at the last in any query.......but in group by clause u can't use use that becoz u group according to column then no ordering is needed there......if u want to filter something then u can use having clause and later if u need to arrange then u can use order by clause.........
i hope this eg.l gives u some clarification....
e.g
select deptno,count(empno)
from dept
group by deptno
having count(empno) > 10
order by deptno -
Analytic Functions with GROUP-BY Clause?
I'm just getting acquainted with analytical functions. I like them. I'm having a problem, though. I want to sum up the results, but either I'm running into a limitation or I'm writing the SQL wrong. Any hints for me?
Hypothetical Table SALES consisting of a DAY_ID, PRODUCT_ID, PURCHASER_ID, PURCHASE_PRICE lists all the
Hypothetical Business Question: Product prices can fluctuate over the course of a day. I want to know how much per day I would have made had I sold one each of all my products at their max price for that day. Silly question, I know, but it's the best I could come up with to show the problem.
INSERT INTO SALES VALUES(1,1,1,1.0);
INSERT INTO SALES VALUES(1,1,1,2.0);
INSERT INTO SALES VALUES(1,2,1,3.0);
INSERT INTO SALES VALUES(1,2,1,4.0);
INSERT INTO SALES VALUES(2,1,1,5.0);
INSERT INTO SALES VALUES(2,1,1,6.0);
INSERT INTO SALES VALUES(2,2,1,7.0);
INSERT INTO SALES VALUES(2,2,1,8.0);
COMMIT;
Day 1: Iif I had sold one product 1 at $2 and one product 2 at $4, I would have made 6$.
Day 2: Iif I had sold one product 1 at $6 and one product 2 at $8, I would have made 14$.
The desired result set is:
DAY_ID MY_MEASURE
1 6
1 14The following SQL gets me tantalizingly close:
SELECT DAY_ID,
MAX(PURCHASE_PRICE)
KEEP(DENSE_RANK FIRST ORDER BY PURCHASE_PRICE DESC)
OVER(PARTITION BY DAY_ID, PRODUCT_ID) AS MY_MEASURE
FROM SALES
ORDER BY DAY_ID
DAY_ID MY_MEASURE
1 2
1 2
1 4
1 4
2 6
2 6
2 8
2 8But as you can see, my result set is "longer" than I wanted it to be. I want a single row per DAY_ID. I understand what the analytical functions are doing here, and I acknowledge that I am "not doing it right." I just can't seem to figure out how to make it work.
Trying to do a sum() of max() simply does not work, nor does any semblance of a group-by clause that I can come up with. Unfortunately, as soon as I add the windowing function, I am no longer allowed to use group-by expressions (I think).
I am using a reporting tool, so unfortunately using things like inline views are not an option. I need to be able to define "MY_MEASURE" as something the query tool can apply the SUM() function to in its generated SQL.
(Note: The actual problem is slightly less easy to conceptualize, but solving this conundrum will take me much closer to solving the other.)
I humbly solicit your collective wisdom, oh forum.Thanks, SY. I went that way originally too. Unfortunately that's no different from what I could get without the RANK function.
SELECT DAY_ID,
PRODUCT_ID,
MAX(PURCHASE_PRICE) MAX_PRICE
FROM SALES
GROUP BY DAY_ID,
PRODUCT_ID
ORDER BY DAY_ID,
PRODUCT_ID
DAY_ID PRODUCT_ID MAX_PRICE
1 1 2
1 2 4
2 1 6
2 2 8 -
Columns not to be included in group by clause
I have a select query where i need to display count of records group by state_name
In my main select query i need to include two more columns which are not be included in group by clause so that the number of records displayed does not increase
I need to pass all these values from front end application so that i get count of records only by statename
But when i include these two columns in my select query my query is throwing an error bcoz i have not included them in my group by
How can we prevent this by not adding it to group by clauseOne general approach is (using the emp dept example)
I want
deptno dname, count(distinct empno)
I can do that
select d.deptno, d.dname, count(distinct e.empno)
from dept d, emp e
where e.deptno=d.deptno
group by d.deptno, d.dname;
or
select d.deptno, d.dname, count_emp
from dept d,
(select e.deptno, count(distinct empno)
from emp e
group by e.deptno
where d.deptno = e.deptno
or depending on version (you don't mention versionk, though most questions have version dependent answers)
select deptno
, dname
, (select count(distinct empno) from emp e where e.deptno=d.deptno)
from dept d
Obviously you can also use the FIRST and the LAST function to avoid having to include a column in the GROUP BY clause.
Sybrand Bakker
Senior Oracle DBA
Maybe you are looking for
-
How do I make FF4 look like FF3.6? I want the same buttons in the same places.
I want the FF4 UI to look exactly like my FF3.6 UI. I want the same buttons in the same places. I have reverted to FF3.6 until this issue is solved. I do NOT like the new UI.
-
Automatic update of vendor code during plant to plant Transfer
Hi all, How to configure automatic update of vendor code during plant to plant Transfer. Regards KK
-
I have apps on my iphone 3gs that I am not playing or using any longer, when I sync they are automatically reloaded, is there any way that one I remove the items that they can be archived w/in the app store?
-
Hi all, I've produced a website with iWeb'08 on my old mac book (mac os 10.4.11) a couple of years ago. Does anyone know how to transfer the iWeb file from this mac to a newer one (with mac os 10.6 and iWeb'09). I've tried a few times, but wasn't suc
-
EntityManager no longer being injected after upgrade
I upgraded the version of JSF being used by the Sun Java Application Server 9 to 1.2_02 by using the upgrade jar on the download site. After doing this, it appears that the JPA EntityManager is no longer being injected (I keep getting a NullPointer e