How to create an Oracle One-to-Many Statistics View? - oracle

I have three tables need to join statistics.The A table corresponds to multiple rows in the B table, and B has a state. I need to count the number of scrapped statuses in B and some attributes of the rows in non-rejected state, and finally grouped by A's barcode, but I don't know how to query B in different states in a query and count them in an A. I tried following codes, but nothing queried.
select
a.barcode barcode
, count(b.id) effectiveNum
, count(b2.id) scraps
, sum(b.x * c.y)
from A a
, B b
, B b2
, C c
where a.id = b.Aid
and a.id = b2.Aid
and b2.state = -1000
and b.id = c.Bid
group by a.barcode
Who can help me please?

I think you need to LEFT-JOIN in order to accept empty Lists in B. But as APC said, some example-data would be great.
SELECT a.barcode barcode,
COUNT (b.id) effectiveNum,
COUNT (b2.id) scraps,
SUM (b.x * c.y)
FROM A a
LEFT JOIN B b ON a.id = b.Ai
LEFT JOIN B b2 ON a.id = b2.Aid AND b2.state = -1000
LEFT JOIN C c ON b.id = c.Bid
WHERE 1 = 1 -- Filter A here if needed
GROUP BY a.barcode

Related

How to combine 2 teradata queries into one

can someone please help me in combining these 2 Teradata queries into a single query? The tables - cdb.dim_party_doc_id, cdb.dim_doc_issuer, mdb.fp_account_entity_map do not have customer_account_number in them, so I not able to directly join all these tables in a single query directly.
Thanks a lot!!
SELECT
det.cust_id AS customer_account_number,
c.encrypt_val AS ssn_encrypted,
det.cust_first_name AS name_1,
bal.BALANCE_AMT AS principal
FROM
cdb.DIM_CUSTOMER det
INNER JOIN
cdb.fact_stored_val_acct_dly bal
ON det.cust_id = bal.customer_id AND bal.curr_cd='USD' and bal.acct_type_code='SBA'
INNER JOIN
cdb.dim_party_acct_map b
ON bal.customer_id = b.cust_id
INNER JOIN
cdb.dim_party_doc_id c
ON b.party_key = c.party_key
AND c.status = 'A'
INNER JOIN
cdb.dim_doc_issuer d
ON c.doc_issuer_id = d.doc_issuer_id
AND d.doc_type = 'TAX_ID'
AND d.doc_subtype = 'SSN'
and
SELECT
own.owner_id AS customer_account_number,
entity.entity_id AS dd_number
FROM
mdb.fp_account_owner_map own
LEFT JOIN
mdb.fp_account_entity_map entity
ON own.fp_account_id = entity.fp_account_id
WHERE
entity.entity_type in (12)
AND
own.product_id in (5501)
Below query solves my problem
SELECT
det.cust_id AS customer_account_number,
temp.direct_deposit_account_number AS account_number,
c.encrypt_val AS ssn_encrypted,
det.cust_first_name AS name_1,
bal.BALANCE_AMT AS principal
FROM
cdb.DIM_CUSTOMER det
LEFT JOIN
cdb.fact_stored_val_acct_dly bal
ON det.cust_id = bal.customer_id AND bal.curr_cd='USD' and bal.acct_type_code='SBA'
INNER JOIN
cdb.dim_party_acct_map b
ON bal.customer_id = b.cust_id
INNER JOIN
cdb.dim_party_doc_id c
ON b.party_key = c.party_key
AND c.status = 'A'
INNER JOIN
cdb.dim_doc_issuer d
ON c.doc_issuer_id = d.doc_issuer_id
AND d.doc_type = 'TAX_ID'
AND d.doc_subtype = 'SSN'
INNER JOIN
(SELECT
own.owner_id AS customer_id,
entity.entity_id AS direct_deposit_account_number
FROM mdb.fp_account_owner_map own
LEFT JOIN
mdb.fp_account_entity_map entity
ON own.fp_account_id = entity.fp_account_id
WHERE entity.entity_type in (12)
AND own.product_id in (5501)) AS temp
ON customer_account_number=temp.customer_id

How to query names from a record with multiple IDs in LINQ

I have a table [A] that has columns such as CreatedBy(ID), AuthorizedBy(ID), SentTo(ID) and I need to join them to a table [B] containing user names (UserID, FullName). How can I write a join that connects each record of table A to multiple records in table B to fill in the CreatedBy/AuthorizedBy/SentTo names using LINQ?
can give try as below , basically you have to join B with A three times
form a in A
join b in B on b.Id = a.Createdby
join b1 in B on b1.Id = a.Authrizedby
join b2 in B on b2.Id = a.SentTo
select new {
a.Id,
CreatedBy= b.FullName,
AuthorizedBy = b1.FullName,
SentTo= b2.FullName};
or
from a in A
select new {
a.ID
CreatedBy= b.FirstOrDefault(a.CreatedBy== b.Id).FullName,
AuthorizedBy = b.FirstOrDefault(a.AuthorizedBy== b.Id).FullName,
SentTo= b.FirstOrDefault(a.SentTo== b.Id).FullName
}

Left outer join is null- additional conditions

I'm trying to find all entries in table a, where there is no matching entry in table b for one specific column (order). I'm using the following:
SELECT *
FROM a
LEFT OUTER JOIN b
ON a.id = b.id
WHERE b.order IS NULL
AND a.result>10
However, the last condition for result doesn't seems to work. It simply lists all the entries from table a, regardless whether result is more than 10 or not.
Any way around this?
Shouldn't your query be as below?
SELECT * FROM a LEFT OUTER JOIN b ON a.id = b.id WHERE b.id IS NULL AND a.result>10

Select a field from a table for two different values from two different tables

I have four tables as shown below.HL_STUDENT,HL_SEM1_CRS and HL_SEM2_CRS tables that has STUDENT as the primary key where as HL_TITLE doesn't have a STUDENT field and has the course number (CRS_NBR) as the key.
HL_STUDENT A
HL_SEM1_CRS B
HL_SEM2_CRS C
HL_CRS_TITLE D
I need to get the STUDENT,CRS-1,CRS1-TITLE-DESC,CRS-2,CRS2-TITLE-DESC as shown below.I need course descripion for both Course 1 and Course 2.
STUDENT CRS-1 CRS1-TITLE-DESC CRS-2 CRS2-TITLE-DESC
1 25 MATH 35 HISTORY
2 35 HISTORY 25 MATH
I was thinking of getting the solution by joining the HL_CRS_TITLE Table twice with different ALIAS as shown below.
SELECT DISTINCT A.STUDENT
,B.CRS_1
,D.CRS_TITLE_DESC
,C.CRS_2
,E.CRS_TITLE_DESC
FROM HL_STUDENT A
LEFT JOIN HL_SEM1_CRS B ON A.STUDENT = B.STUDENT
LEFT JOIN HL_CRS_TITLE D ON D.CRS_NBR = B.CRS_1
LEFT JOIN HL_SEM2_CRS B ON A.STUDENT = B.STUDENT
LEFT JOIN HL_CRS_TITLE E ON E.CRS_NBR = B.CRS_2
Can you please suggest a better way to get the solution?
I'm querying against ORACLE DB.
Thanks for your help.
I think you are looking for a way to get course title for the records of both the semesters without the need of joining HL_CRS_TITLE two times.
I ran into a similar situation once and created a function to serve the purpose.
--Function DDL
CREATE OR REPLACE FUNCTION F_GET_CRS_TITLE (IN_CRS_NBR IN NUMBER)
RETURN VARCHAR2
RESULT_CACHE
AS
LV_CRS_TITLE_DESC VARCHAR2(100);
BEGIN
SELECT CRS_TITLE_DESC
INTO LV_CRS_TITLE_DESC
FROM HL_CRS_TITLE
WHERE CRS_NBR = IN_CRS_NBR;
RETURN LV_CRS_TITLE_DESC;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN 'NO_COURSE_EXISTS';
END;
/
You can re-write your query like below:
SELECT DISTINCT A.STUDENT
,B.CRS_1
,F_GET_CRS_TITLE(B.CRS_1)
,C.CRS_2
,F_GET_CRS_TITLE(C.CRS_2)
FROM HL_STUDENT A
LEFT JOIN HL_SEM1_CRS B ON A.STUDENT = B.STUDENT
LEFT JOIN HL_SEM2_CRS C ON A.STUDENT = C.STUDENT;
As I understand the problem is in duplicates if you join students and courses in first semester and join it in second semester you see cross joined courses?
If its true you may use FULL JOIN between courses and join it with students and titles
SELECT DISTINCT A.STUDENT
,B.CRS_1
,D.CRS_TITLE_DESC
,B.CRS_2
,E.CRS_TITLE_DESC
FROM HL_STUDENT A
JOIN (SELECT NVL(B1.STUDENT, B2.STUDENT) as STUDENT, B1.CRS_1, B2.CRS_2
FROM HL_SEM1_CRS B1
FULL JOIN HL_SEM2_CRS B2 ON B1.STUDENT = B2.STUDENT AND B1.CRS_1 = B2.CRS_2) B ON A.STUDENT = B.STUDENT
LEFT JOIN HL_CRS_TITLE D ON D.CRS_NBR = B.CRS_1
LEFT JOIN HL_CRS_TITLE E ON E.CRS_NBR = B.CRS_2
example without double join to HL_CRS_TITLE.
SELECT DISTINCT A.STUDENT
,B.CRS_1
,nvl2(B.CRS_1, D.CRS_TITLE_DESC, null) as CRS_TITLE_DESC_1
,B.CRS_2
,nvl2(B.CRS_2, D.CRS_TITLE_DESC, null) as CRS_TITLE_DESC_2
FROM HL_STUDENT A
JOIN (SELECT NVL(B1.STUDENT, B2.STUDENT) as STUDENT,nvl(B1.CRS_1, B2.CRS_2) as CRS,B1.CRS_1, B2.CRS_2
FROM HL_SEM1_CRS B1
FULL JOIN HL_SEM2_CRS B2 ON B1.STUDENT = B2.STUDENT AND B1.CRS_1 = B2.CRS_2) B ON A.STUDENT = B.STUDENT
LEFT JOIN HL_CRS_TITLE D ON D.CRS_NBR = B.CRS

Multiple Joins LINQ Query performance

I'm new to LINQ and have very little knowledge.
I have the following complex query. it runs 3 or 4 times slower than the stored procedure which i translated to LINQ.
any tips for me to make it run faster?
var result = from a in db.A
join al in db.AL.Where(q => q.CurrentLocation == 1) on a.AID equals al.AID into tmp_al
from al in tmp_al.DefaultIfEmpty()
join l in db.Lon al.LID equals l.LID into tmp_l
from l in tmp_l.DefaultIfEmpty()
join r in db.R on l.RID equals r.RID into tmp_r
from r in tmp_r.DefaultIfEmpty()
join b in db.B on r.BID equals b.BID into tmp_b
from b in tmp_b.DefaultIfEmpty()
join ap in db.AP.Where(q => q.CurrentProtocol == 1) on a.AID equals ap.AID into tmp_ap
from ap in tmp_ap.DefaultIfEmpty()
join p in db.P on ap.PID equals p.PID into tmp_p
from p in tmp_p.DefaultIfEmpty()
join s in db.S on a.SID equals s.SID into tmp_s
from s in tmp_s.DefaultIfEmpty()
join ans in db.AS on a.ASID equals ans.ASID into tmp_ans
from ans in tmp_ans.DefaultIfEmpty()
join pr in db.P on p.PI equals pr.PID into tmp_pr
from pr in tmp_pr.DefaultIfEmpty()
where a.Active == 1
group a by new { a.Active, pr.LN, pr.FN, b.BN, r.RID, r.R1, p.PN, s.S1, ans.AS1 }
into grp
orderby grp.Key.BN, grp.Key.R1, grp.Key.PN, grp.Key.S1, grp.Key.AS1
select new
{
PIName = grp.Key.LN + " " + grp.Key.FN,
BN = grp.Key.BN,
RID = grp.Key.RID,
R = grp.Key.R1,
PN = grp.Key.PN,
S = grp.Key.S1,
AS = grp.Key.AS1,
NumberOA = grp.Count()
};
Thanks for your answers. #Albin Sunnanbo: i dont know how to check the execution plans. my LINQ runs correctly and produces the required output. it is just slow. I would like to speeden it up. #usr: the original sql is as follows:
sorry about the silly table names. the original code is confidential. so i'm not posting the complete table names.
CREATE PROCEDURE [dbo].[report_CBRP] --
AS
SELECT LN + ' ' + FN As PIN, BN, R.RID, R, PN,
S, AS, COUNT(*) As NOA
FROM A
LEFT JOIN AL
ON A.AID = AL.AID
AND AL.CL = 1
LEFT JOIN L
ON AL.LID = L.LID
LEFT JOIN R
ON L.RID = R.RID
LEFT JOIN B
ON R.BID = B.BID
LEFT JOIN AP
ON A.AID = AP.AID
AND AP.CPl = 1
LEFT JOIN P
ON AP.PID = P.PID
LEFT JOIN S
ON A.SID = S.SID
LEFT JOIN AS
ON A.ASID = AS.ASID
LEFT JOIN P
ON P.PI = P.PID
GROUP BY A.A, LN , FN , B.BN, R.RID, R.R, P.PN,
S.S, AS.AS
HAVING A.A = 1
ORDER BY B.BN, R.R, P.PN, S, AS
GO
It seems you're doing SQL hard life here.
In general, try to avoid so many joins, but rather break them into few small queries.
More than that, you're performing a group by which in itself is an expensive operation, let alone with so many columns
I've noticed that you're joining all the columns in each table. Try to select only the relevant columns.
Also noticed that few of the tables aren't used in the group by like al, ap and l. Do you need them at all??
Use AsNoTracking() for readonly data from EF. In that way you speed up things.
Use SQL Views

Resources