We are working on PeopleSoft ELM 9.2 and I'm not finding what I need in any of the OOB queries so I'm attempting to build one. We need to get a "First Time Pass Rate" score, or the average of how many people pass a learning course on their first try. Ideally we would have the data for each attempt so that we could also see how many attempts a particular person or course has prior to getting a passing score.
Our setup includes SCORM 1.2 modules that pass off a score to the LMS for verification that a passing score was received. The closest I've been able to come so far is to get a "Pass/Fail" score but either my query unions are incorrect or the data is incorrect as it returns extraneous data that is not relevant to the other data returned or (if I force distinct values) it returns sporadically accurate data. Below is the SQL that I'm using if it helps.
Has anyone tried to build this kind of query before and how did you do it? :)
SELECT DISTINCT D1X.XLATLONGNAME, D.LM_ORGANIZATION_ID, D.LM_ORG_DESCR,
D.LM_HR_EMPLID, TO_CHAR(D.LM_HIRE_DT,'YYYY-MM-DD'), D.FIRST_NAME,
D.LAST_NAME, C.LM_CS_LONG_NM, C.LM_ACT_CD, A.LM_LC_LONG_NM, A.LM_LC_ID,
B12X.XLATLONGNAME, TO_CHAR(B.LM_COMPL_DT,'YYYY-MM-DD'), B.LM_ENRLMT_ID,
E15X.XLATLONGNAME
FROM PS_LM_LC A, PS_LM_ENRLMT B LEFT OUTER JOIN PSXLATITEM B12X ON
B12X.FIELDNAME='LM_STTS' AND B12X.FIELDVALUE=B.LM_STTS AND B12X.EFF_STATUS =
'A' AND B12X.EFFDT = (SELECT MAX(EFFDT) FROM PSXLATITEM TB WHERE
TB.FIELDNAME=B12X.FIELDNAME AND TB.FIELDVALUE=B12X.FIELDVALUE AND
TB.EFF_STATUS = 'A' AND TB.EFFDT <= TO_DATE(TO_CHAR(SYSDATE,'YYYY-MM-
DD'),'YYYY-MM-DD') ), PS_LM_ACT_CI_VW C, PS_LM_PERS_DTL_VW D LEFT OUTER JOIN
PSXLATITEM D1X ON D1X.FIELDNAME='LM_ACTIVE' AND D1X.FIELDVALUE=D.LM_ACTIVE
AND D1X.EFF_STATUS = 'A' AND D1X.EFFDT = (SELECT MAX(EFFDT) FROM PSXLATITEM
TB WHERE TB.FIELDNAME=D1X.FIELDNAME AND TB.FIELDVALUE=D1X.FIELDVALUE AND
TB.EFF_STATUS = 'A' AND TB.EFFDT <= TO_DATE(TO_CHAR(SYSDATE,'YYYY-MM-
DD'),'YYYY-MM-DD') ), PS_LM_ENR_LC_BL_VW E LEFT OUTER JOIN PSXLATITEM E15X
ON E15X.FIELDNAME='LM_PASS_STTS' AND E15X.FIELDVALUE=E.LM_PASS_STTS AND
E15X.EFF_STATUS = 'A' AND E15X.EFFDT = (SELECT MAX(EFFDT) FROM PSXLATITEM TB
WHERE TB.FIELDNAME=E15X.FIELDNAME AND TB.FIELDVALUE=E15X.FIELDVALUE AND
TB.EFF_STATUS = 'A' AND TB.EFFDT <= TO_DATE(TO_CHAR(SYSDATE,'YYYY-MM-
DD'),'YYYY-MM-DD') )
WHERE ( A.LM_ACT_ID = B.LM_ACT_ID
AND A.LM_ACT_ID = C.LM_ACT_ID
AND D.LM_PERSON_ID = B.LM_PERSON_ID
AND D.BUSINESS_UNIT IN ('00340','00235')
AND B.LM_ENRL_DT BETWEEN TO_DATE(:1,'YYYY-MM-DD') AND TO_DATE(:2,'YYYY-MM-DD')
AND D.LM_HR_EMPLID = :3
AND D.LM_ACTIVE = :4
AND B.LM_STTS = 'COMP'
AND A.LM_LC_ID = E.LM_LC_ID
AND E.LM_PASS_STTS IN ('FAIL','PASS'))
Related
I am fetching data from SQLite database using following query:
SELECT p.sent,
e.*,
e.no _id
FROM ecare e
LEFT OUTER JOIN pweb p ON e.h_id = p.h_id
WHERE (ant = 'N' or ant = 'D')
GROUP BY e.h_id
ORDER BY p.sent
By using the above SQLite query, I am getting all the records belonging to sent (where sent = 1 and sent = 0).
Now, I would like to get only those records from database, where sent status is sent = 0. (In short, I don't want to fetch all the records belonging to sent, or records where sent = 1).
Have you tried with below query ?
SELECT p.sent,e.*, e.no _id from ecare e LEFT JOIN pweb p ON
e.h_id=p.h_id WHERE (ant = 'N' or ant = 'D') AND p.sent = '0' GROUP
BY e.h_id
Check below query for your question:
return db.rawQuery("SELECT p.sent,e.*, e.no _id from ecare e LEFT OUTER JOIN pweb p ON e.h_id=p.h_id WHERE (ant = 'N' or ant = 'D') AND p.sent = '1' GROUP BY e.h_id ORDER BY p.sent ", null);
You are already filtering on the ant column.
Adding a filter for sent works the same way:
SELECT ...
...
WHERE (ant = 'N' OR ant = 'D')
AND sent = 0
...
Can anybody help me how to find a component existence in all layers and models installed in that layer. i.e find all the layers and models in which a particular component(ax 2012) exists.
For example how to find all the layers and models in which CustTable exists.
Is there any class or table that stores this information.
please help me. Thanks in advance.
Comment is limited :(
Do you need to search through source code? Are you searching for merge candidates? Tell me your business requirement.
Here is the query returning elements that contains CustTable within selected models:
SELECT
me.Name ElementName
, Layer.Name Layer
, mm.Name ModelName
, ElementTypes.ElementTypeName
FROM ModelElement me
JOIN ModelElementData med
ON med.ElementHandle = me.ElementHandle
AND me.ParentHandle = 0 -- only root elements
JOIN ModelManifest mm
ON mm.ModelId=med.ModelId
JOIN Layer
ON Layer.Id = med.LayerId
JOIN ElementTypes
ON me.ElementType = ElementTypes.ElementType
WHERE EXISTS (
SELECT null
FROM ModelElement child
JOIN Sources s
ON s.SourceHandle = child.ElementHandle
AND s.LayerId = med.LayerId
AND child.RootHandle = med.ElementHandle
WHERE cast([SourceText] as nvarchar(max)) like '%CustTable%'
)
AND mm.Name IN ('Foundation','I4C')
You can try search within _model databese with next query (this searcehs all code references - table, class, form, dataset, ...):
SELECT TOP 1000 [SourceHandle]
, met.ElementTypeName
, ro.Name object
, me.Name method
, l.Name Layer
, mm.Name Model
, cast([SourceText] as nvarchar(max)) sourceTxt
FROM [Sources] s
join ModelElement me on me.ElementHandle=s.SourceHandle
join ElementTypes met on met.ElementType=me.ElementType
join ModelElement ro on ro.ElementHandle=me.RootHandle
left join ModelElementData med on med.ElementHandle=s.SourceHandle and med.LayerId=s.LayerId and med.ElementHandle=me.ElementHandle
left join Layer l on l.Id=s.LayerId
left join ModelManifest mm on mm.ModelId=med.ModelId
WHERE cast([SourceText] as nvarchar(max)) like '%CustTable%'
If you need all records, remove TOP 1000.
SELECT DISTINCT
ro.Name object,
ro.ElementType type,
l.Name Layer,
mm.Name Model
FROM Sources s
join ModelElement me on
me.ElementHandle = s.SourceHandle
join ElementTypes met
on met.ElementType = me.ElementType
join ModelElement ro
on ro.ElementHandle = me.RootHandle
left join ModelElementData med
on med.ElementHandle = s.SourceHandle
and med.LayerId = s.LayerId
and med.ElementHandle = me.ElementHandle
left join Layer l
on l.Id = s.LayerId
left join ModelManifest mm
on mm.ModelId = med.ModelId
where ro.Name = 'InventDim' order by mm.Name, ro.ElementType
In addition to the query suggested by the authors, a small change was made according to my requirement is giving the right results.
Using PL-SQL, I need to find the record with the lastest INVC_LN_ITEM_STAT_START_DT value within a group of records that share the same value for SHPMNT_LN_ITEM_KEY and RPT_PER_KEY.
How else might this be done? Are there analytical functions for this type of query?
SELECT
m1.*
FROM
HD_INVC_LN_ITEM_STAT m1
LEFT OUTER JOIN HD_INVC_LN_ITEM_STAT m2
ON (
m1.SHPMNT_LN_ITEM_KEY = m2.SHPMNT_LN_ITEM_KEY
AND m1.RPT_PER_KEY = m2.RPT_PER_KEY
AND m1.INVC_LN_ITEM_STAT_START_DT < m2.INVC_LN_ITEM_STAT_START_DT)
WHERE
m2.SHPMNT_LN_ITEM_KEY IS NULL
ORDER BY
m1.SHPMNT_LN_ITEM_KEY
,m1.RPT_PER_KEY
,m1.INVC_LN_ITEM_STAT_CD
,m1.INVC_LN_ITEM_STAT_START_DT
How about this?
SELECT
HD_INVC_LN_ITEM_STAT1.*
FROM
HD_INVC_LN_ITEM_STAT HD_INVC_LN_ITEM_STAT1
INNER JOIN
(
SELECT
HD_INVC_LN_ITEM_STAT2.SHPMNT_LN_ITEM_KEY
,HD_INVC_LN_ITEM_STAT2.RPT_PER_KEY
,MAX(HD_INVC_LN_ITEM_STAT2.INVC_LN_ITEM_STAT_START_DT) AS MAX_INVC_LN_ITEM_STAT_START_DT
FROM
HD_INVC_LN_ITEM_STAT HD_INVC_LN_ITEM_STAT2
GROUP BY
HD_INVC_LN_ITEM_STAT2.SHPMNT_LN_ITEM_KEY
,HD_INVC_LN_ITEM_STAT2.RPT_PER_KEY
) HD_INVC_LN_ITEM_STAT2
ON
HD_INVC_LN_ITEM_STAT1.SHPMNT_LN_ITEM_KEY = HD_INVC_LN_ITEM_STAT2.SHPMNT_LN_ITEM_KEY
AND HD_INVC_LN_ITEM_STAT1.RPT_PER_KEY
= HD_INVC_LN_ITEM_STAT2.RPT_PER_KEY
AND HD_INVC_LN_ITEM_STAT1.INVC_LN_ITEM_STAT_START_DT = HD_INVC_LN_ITEM_STAT2.MAX_INVC_LN_ITEM_STAT_START_DT
ORDER BY
HD_INVC_LN_ITEM_STAT1.SHPMNT_LN_ITEM_KEY
,HD_INVC_LN_ITEM_STAT1.RPT_PER_KEY
,HD_INVC_LN_ITEM_STAT1.INVC_LN_ITEM_STAT_CD
,HD_INVC_LN_ITEM_STAT1.INVC_LN_ITEM_STAT_START_DT;
It's longer but arguably more intuitive. I would like other people's opinions on which is more efficient.
I have query that runs as part of a function which produces a one row table full of counts, and averages, and comma separated lists like this:
select
(select
count(*)
from vw_disp_details
where round = 2013
and rating = 1) applicants,
(select
count(*)
from vw_disp_details
where round = 2013
and rating = 1
and applied != 'yes') s_applicants,
(select
LISTAGG(discipline, ',')
WITHIN GROUP (ORDER BY discipline)
from (select discipline,
count(*) discipline_number
from vw_disp_details
where round = 2013
and rating = 1
group by discipline)) disciplines,
(select
LISTAGG(discipline_count, ',')
WITHIN GROUP (ORDER BY discipline)
from (select discipline,
count(*) discipline_count
from vw_disp_details
where round = 2013
and rating = 1
group by discipline)) disciplines_count,
(select
round(avg(util.getawardstocols(application_id,'1','AWARD_NAME')), 2)
from vw_disp_details
where round = 2013
and rating = 1) average_award_score,
(select
round(avg(age))
from vw_disp_details
where round = 2013
and rating = 1) average_age
from dual;
Except that instead of 6 main sub-queries there are 23.
This returns something like this (if it were a CSV):
applicants | s_applicants | disciplines | disciplines_count | average_award_score | average_age
107 | 67 | "speed,accuracy,strength" | 3 | 97 | 23
Now I am programmatically swapping out the "rating = 1" part of the where clauses for other expressions. They all work rather quickly except for the "rating = 1" one which takes about 90 seconds to run and that is because the rating column in the vw_disp_details view is itself compiled by a sub-query:
(SELECT score
FROM read r,
eval_criteria_lookup ecl
WHERE r.criteria_id = ecl.criteria_id
AND r.application_id = a.lgo_application_id
AND criteria_description = 'Overall Score'
AND type = 'ABC'
) reader_rank
So when the function runs this extra query seems to slow everything down dramatically.
My question is, is there a better (more efficient) way to run a query like this that is basically just a series of counts and averages, and how can I refactor to optimize the speed so that the rating = 1 query doesn't take 90 seconds to run.
You could choose to MATERIALIZE the vw_disp_details VIEW. That would pre-calculate the value of the rating column. There are various options for how up-to-date a materialized view is kept, you would probably want to use the ON COMMIT clause so that vw_disp_details is always correct.
Have a look at the official documentation and see if that would work for you.
http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_6002.htm
Do all most of your queries in only one. Instead of doing:
select
(select (count(*) from my_tab) as count_all,
(select avg(age) from my_tab) as avg_age,
(select avg(mypkg.get_award(application_id) from my_tab) as_avg-app_id
from dual;
Just do:
select count(*), avg(age),avg(mypkg.get_award(application_id)) from my_tab;
And then, maybe you can do some union all for the other results. But this step all by itself should help.
I was able to solve this issue by doing two things: creating a new view that displayed only the results I needed, which gave me marginal gains in speed, and in that view moving the where clause of the sub-query that caused the lag into the where clause of the view and tacking on the result of the sub-query as column in the view. This still returns the same results thanks to the fact that there are always going to be records in the table the sub-query accessed for each row of the view query.
SELECT
a.application_id,
util.getstatus (a.application_id) status,
(SELECT score
FROM applicant_read ar,
eval_criteria_lookup ecl
WHERE ar.criteria_id = ecl.criteria_id
AND ar.application_id = a.application_id
AND criteria_description = 'Overall Score' //THESE TWO FIELDS
AND type = 'ABC' //ARE CRITERIA_ID = 15
) score
as.test_total test_total
FROM application a,
applicant_scores as
WHERE a.application_id = as.application_id(+);
Became
SELECT
a.application_id,
util.getstatus (a.application_id) status,
ar.score,
as.test_total test_total
FROM application a,
applicant_scores as,
applicant_read ar
WHERE a.application_id = as.application_id(+)
AND ar.application_id = a.application_id(+)
AND ar.criteria_id = 15;
I need to select data from four tables based on only one.
In my 'calculated' table, I have all the records I need.
But I need to retrieve some other info for each record, from 'programs', 'term' and 'imported' tables.
'calculated' has ID from 'programs'.
But, to achieve a record from 'imported', I need to join the 'item' table, because 'item' has ID from 'programs' and from 'imported'.
'term' has ID from 'imported'.
So, I tried this:
select c.date,
p.name,
c.name1,
c.name2,
t.date,
i.version,
c.price1,
c.price2,
c.price3
from calculated c, programs p, term t, imported i, item it
where c.programs_id = p.programs_id
and c.programs_id = it.programs_id
and it.imported_id = i.imported_id
and i.term_id = t.term_id;
But when I use count(*) on 'calculated', I get 30k of records, and from my select statement I get more than 130 millions of records.
What am I doing wrong?
What should I do for this to work?
If all duplicates rows are equivalent, u can try smth like this
select c.date,
p.name,
c.name1,
c.name2,
t.date,
i.version,
c.price1,
c.price2,
c.price3
from calculated c, programs p, term t, imported i
where c.programs_id = p.programs_id and
(select imported_id from item it where c.programs_id = it.programs_id and rownum = 1) = i.imported_id
and i.term_id = t.term_id;
where "rownum = 1" is restriction on the selection of one line for oracle.
you forgot to join term table.
Probably you need to add
and t.term_id = i.term_id