Using "With" SQL on Oracle 10g causing errors - sql

First ill tell you what the logic in my code is, after my last post it was pointed out to me that my procedure was inefficient and that i should think about logic of my approach..
To put it simply, i want to join a bunch of tables and filter them out to reflect a certain scheme, the process in "Z" in the bellow code
And then parse through that data using y on z...
Looking at the examples online i cant see why this code dosnt work, i have read in a few places that it may be a oracle 10g issue but note sure.. any recommendations would be great
The error i get is "ORA-00904: "Z"."COMMENTS": invalid identifier"
with
z as
(
Select *
FROM
(
iacd_note c
inner join iacd_ncr_note e on C.NOTE_ID=E.NOTE_ID
inner join iacd_ncr f on E.NCR_ID=F.NCR_ID
inner join iacd_ncr_iac g on F.NCR_ID=G.NCR_ID
)
WHERE c.create_date >= date'2014-01-01'
AND c.create_date < date'2014-12-31'
AND G.SCHEME_ID in (36,37,38,25,26,27,28,29,30,31,32,33,34,35,39,40,44,42,43,45, 48,49,50,51,52,55,56,57,58,68,69,70,71)
),
y as
(
Select *
From iacd_asset
)
SELECT y.bridge_no, COUNT(*) AS comment_cnt
FROM y INNER JOIN z
ON REGEXP_LIKE(z.comments, '(^|\W)BN' || y.bridge_no || '(\W|$)', 'i')
GROUP BY y.bridge_no
ORDER BY comment_cnt;
Z.COMMENTS should be part of the merges happening in z

This subquery is invalid SQL syntax:
Select *
FROM
(
iacd_note c
inner join iacd_ncr_note e on C.NOTE_ID=E.NOTE_ID
inner join iacd_ncr f on E.NCR_ID=F.NCR_ID
inner join iacd_ncr_iac g on F.NCR_ID=G.NCR_ID
)
WHERE ...
You can't put parentheses around the FROM clause. Instead:
Select *
FROM iacd_note c
inner join iacd_ncr_note e on C.NOTE_ID=E.NOTE_ID
inner join iacd_ncr f on E.NCR_ID=F.NCR_ID
inner join iacd_ncr_iac g on F.NCR_ID=G.NCR_ID
WHERE ...

Looks like the output of a with clause may not have the same column names as the original tables, so i selected all of z and noticed there was an odd automated name for the row i was after...

Related

How to join Multiple

This is the code example
for three tables and I made a link on them
Now I want to add the age column from table D
SELECT A.COD,a.namee, B.NAMEE,C.NAMEE
FROM ((A INNER JOIN B ON A.COD = B.COD)
LEFT JOIN C ON A.COD = C.COD)
I mean, this code is expected
SELECT A.COD, a.name , B.NAME,C.NAME ,D.Age
FROM ((A INNER JOIN B ON A.COD = B.COD)
LEFT JOIN C ON A.COD = C.COD) , D
But in access, an error message appears, the text of the message says that the JOIN method is not supported
Is there a way to solve this?
Access does not allow to do a direct cross-join (operator ",") involving an SQL expression that includes a different type of join. The solution is as simple as enclosing the first operation between parentheses and add another SELECT, as follows:
SELECT T_A.COD, T_A.Name_ , T_B.Name_, T_C.Name_, T_D.Age
FROM
(
SELECT T_A.COD, T_A.Name_ , T_B.Name_, T_C.Name_
FROM
( T_A
INNER JOIN
T_B
ON T_A.COD = T_B.COD)
LEFT JOIN
T_C
ON T_A.COD = T_C.COD
)
, T_D
My advice is that you always enclose in a SELECT every individual join operation (with the exception of cross-joins) as good programming practice. There is no problem in doing a series of cross-joins because the cross-join operator is associative.

CALCULATE PERCENT BY DEVIDING AGREGATED VALUE ON TOTAL

I'm trying to write a query that aggregates a column by a category and then find a percent of that category from total categories
WITH USERS_ENERGY AS
(SELECT D.REGION_ID,E.YEAR_DESC,HOME_TYPE_ID,OWNERSHIP_TYPE_ID,B.ELECTRICITY_TYPE_KEY,SUM(WEIGHT_FINAL) HH_BY_ELECTRICITY_TYPE
FROM
R_FACT_HOUSING_UNIT B
JOIN
RR_DIM_SAMPLE C ON B.SAMPLE_FORM_ID=C.SAMPLE_FORM_ID
JOIN
R_DIM_PLACES D ON C.FRAM_PLACE_ID=D.PLACE_ID
JOIN
R_DIM_YEAR E ON B.ROUND_YEAR=E.ID
JOIN
R_DIM_HOME_TYPE F ON F.HOME_TYPE_ID=B.HOME_TYPE_KEY
JOIN
R_DIM_OWNERSHIP_TYPE G ON G.OWNERSHIP_TYPE_ID=B.OWNERSHIP_TYPE_KEY
WHERE B.ELECTRICITY_TYPE_KEY IN(8200002,8200001)
GROUP BY D.REGION_ID,E.YEAR_DESC,HOME_TYPE_ID,OWNERSHIP_TYPE_ID,B.ELECTRICITY_TYPE_KEY),
ALL_HH AS
(
SELECT REGION_ID,YEAR_DESC,HOME_TYPE_ID,OWNERSHIP_TYPE_ID,SUM(B.WEIGHT_FINAL) TOTAL_HH
FROM
R_FACT_HOUSING_UNIT B
JOIN
RR_DIM_SAMPLE C ON B.SAMPLE_FORM_ID=C.SAMPLE_FORM_ID
JOIN
R_DIM_PLACES D ON C.FRAM_PLACE_ID=D.PLACE_ID
JOIN
R_DIM_YEAR E ON B.ROUND_YEAR=E.ID
JOIN
R_DIM_HOME_TYPE F ON F.HOME_TYPE_ID=B.HOME_TYPE_KEY
JOIN
R_DIM_OWNERSHIP_TYPE G ON G.OWNERSHIP_TYPE_ID=B.OWNERSHIP_TYPE_KEY
WHERE B.ELECTRICITY_TYPE_KEY IN(8200002,8200001)
GROUP BY REGION_ID,YEAR_DESC,HOME_TYPE_ID,OWNERSHIP_TYPE_ID
)
SELECT A."REGION_ID",A."YEAR_DESC",A."HOME_TYPE_ID",A."OWNERSHIP_TYPE_ID",A."ELECTRICITY_TYPE_KEY",A."HH_BY_ELECTRICITY_TYPE",TOTAL_HH FROM USERS_ENERGY A,ALL_HH B WHERE A.REGION_ID=B.REGION_ID AND A.YEAR_DESC=B.YEAR_DESC AND A.HOME_TYPE_ID=B.HOME_TYPE_ID AND A.OWNERSHIP_TYPE_ID=B.OWNERSHIP_TYPE_ID
that was the view I created.
when I tried to test it gave me wrong results
this was my test
SELECT ELECTRICITY_TYPE_KEY,SUM(HH_BY_ELECTRICITY_TYPE),SUM(TOTAL_HH)FROM MASDAR_HEN_3_A_A T
GROUP BY ELECTRICITY_TYPE_KEY
ORDER BY ELECTRICITY_TYPE_KEY
the result was:
but it supposes to be:
so if you devide values on total and add them it supposes to give 100%
Your query is almost impossible to follow. Some helpful advice for your query-writing:
Always use MEANINGFUL table alases, such as y for dim_year. Arbitrary letters are hard to follow.
Always use proper, explicit, standard JOIN syntax. Never use commas in the FROM clause.
As for your view, I think you just need analytic functions. A simpler version (assuming I haven't make mistakes on the table aliases):
SELECT p.REGION_ID, y.YEAR_DESC, ht.HOME_TYPE_ID, ot.OWNERSHIP_TYPE_ID, hu.ELECTRICITY_TYPE_KEY,
SUM(WEIGHT_FINAL) as HH_BY_ELECTRICITY_TYPE
SUM(SUM(WEIGHT_FINAL)) OVER (REGION_ID,YEAR_DESC, HOME_TYPE_ID, OWNERSHIP_TYPE_ID) as TOTAL_HH
FROM R_FACT_HOUSING_UNIT hu JOIN
RR_DIM_SAMPLE
ON hu.SAMPLE_FORM_ID = s.SAMPLE_FORM_ID JOIN
R_DIM_PLACES p
ON s.FRAM_PLACE_ID= p.PLACE_ID JOIN
R_DIM_YEAR y
ON hu.ROUND_YEAR = y.ID JOIN
R_DIM_HOME_TYPE ht
ON ht.HOME_TYPE_ID = hu.HOME_TYPE_KEY JOIN
R_DIM_OWNERSHIP_TYPE ot
ON ot.OWNERSHIP_TYPE_ID= hu.OWNERSHIP_TYPE_KEY
WHERE hu.ELECTRICITY_TYPE_KEY IN (8200002, 8200001)
GROUP BY p.REGION_ID, y.YEAR_DESC, ht.HOME_TYPE_ID, ot.OWNERSHIP_TYPE_ID, hu.ELECTRICITY_TYPE_KEY;
Oracle provides a RATIO_TO_REPORT analytic function to compute % of total for you.
SELECT
d.region_id,
e.year_desc,
home_type_id,
ownership_type_id,
b.electricity_type_key,
SUM(weight_final) hh_by_electricity_type,
100*RATIO_TO_REPORT(SUM(weight_final) OVER ( PARTITION BY REGION_ID,YEAR_DESC, HOME_TYPE_ID, OWNERSHIP_TYPE_ID ) pct_of_total
FROM
r_fact_housing_unit b
JOIN rr_dim_sample c ON b.sample_form_id = c.sample_form_id
JOIN r_dim_places d ON c.fram_place_id = d.place_id
JOIN r_dim_year e ON b.round_year = e.id
JOIN r_dim_home_type f ON f.home_type_id = b.home_type_key
JOIN r_dim_ownership_type g ON g.ownership_type_id = b.ownership_type_key
WHERE
b.electricity_type_key IN (
8200002,
8200001
)
GROUP BY
d.region_id,
e.year_desc,
home_type_id,
ownership_type_id,
b.electricity_type_key;
Here is another example, using the Oracle data dictionary for input data, for readers who do not have data model to test with:
SELECT owner,
sum(bytes) total_bytes,
100*ratio_to_report(sum(bytes)) over () pct_of_total
FROM dba_segments
GROUP BY owner;

how to select count of rows an other table

i'm using this query to select count of comments on other table but it give me error
SELECT
dbo.tblEmails.id, dbo.tblEmails.eTitle, dbo.tblEmails.ePreDesc, dbo.tblEmails.eTags, dbo.tblEmails.eFaDate, dbo.tblEmails.eViewCount,
dbo.tblEmails.ePrice, dbo.tblEmails.eImg, COUNT(tblComments.id) AS cCount
FROM
dbo.tblEmails as tblEmails
INNER JOIN
dbo.tblComments AS tblComments ON dbo.tblEmails.id = dbo.tblComments.PostID
GROUP BY
tblEmails.id, tblEmails.eTitle, tblEmails.ePreDesc, tblEmails.eTags, tblEmails.eFaDate, tblEmails.eViewCount, tblEmails.ePrice, tblEmails.eImg
UPDATE:
error is this :
the text,ntext, and image data types cannot be compared or
stored,except when using IS NULL or LIKE operator.
but i have not image data type in my table
Well, you haven't specified what error text is... But in this particular case it is easy to deduce.
Your problem is incorrect usage of aliases in join and select.
It should be not
INNER JOIN dbo.tblComments AS tblComments ON dbo.tblEmails.id = dbo.tblComments.PostID
but
INNER JOIN dbo.tblComments AS tblComments ON tblEmails.id = tblComments.PostID
And the same story is about select - not dbo.tblEmails.id but tblEmails.id since you've specified alias.
But note - using exact table_name as alias to dbo.table_name looks like a bad idea and may lead to confusion (and in fact, it has lead in your case).
Instead consider using short acronyms for aliases, like this:
SELECT
E.id, E.eTitle, E.ePreDesc, E.eTags,
E.eFaDate, E.eViewCount,E.ePrice, E.eImg,
COUNT(C.id) AS cCount
FROM dbo.tblEmails as E
INNER JOIN dbo.tblComments AS C ON E.id = C.PostID
GROUP BY
E.id, E.eTitle, E.ePreDesc, E.eTags,
E.eFaDate, E.eViewCount,E.ePrice, E.eImg
Do a sub-select to get the count:
SELECT dbo.tblEmails.id, dbo.tblEmails.eTitle, dbo.tblEmails.ePreDesc, dbo.tblEmails.eTags, dbo.tblEmails.eFaDate, dbo.tblEmails.eViewCount,
dbo.tblEmails.ePrice, dbo.tblEmails.eImg,
(select COUNT(*) from dbo.tblComments
where dbo.tblEmails.id = dbo.tblComments.PostID) AS cCount
FROM dbo.tblEmails as tblEmails

Joining SQL Server UDF with params

I have a code I cannot resolve. Can anyone help me, please?
Code:
SELECT
s.*
FROM
tabD d
,tabP p
,dbo.myFunc(d.col1) f
,tabS s
WHERE 1=1
and p.D_ID=d.ID
and s.ID=f.ID
myFunc is an UDF returning a table (containing, inter alia, column ID)
The problem is, that the dbo.myFunc(d.col1) call causes an error
The multi-part identifier "d.col1" could not be bound.
How to rearrange the code to work fine?
(Running on SQL Server)
Use APPLY to pass in row by row parameters into a UDF
And of course use ANSI-92 style joins as a matter of course. Mixing APPLY and the old style "join in the where clause" will cause you headaches: even more so than just not using explicit JOIN syntax
SELECT
s.*
FROM
tabD d
JOIN
tabP p ON p.D_ID=d.ID
CROSS APPLY
dbo.myFunc(d.col1) f
JOIN
tabS s ON s.ID =f.ID
may be this also works
SELECT
d.*,
(Select P.Id from tabP P where P.ID = d.id) P,
(Select S.ID from tabs S where S.ID = d.id) P
FROM
tabD d
OUTER APPLY
dbo.myFunc(d.col1) f
WHERE 1=1
and P.ID=d.ID
and S.ID=f.ID

sql join history table to active table SSRS report

I'm trying to pull results from a database (sql server 2005) which takes 4 tables:
Subscriber S, Member M, ClaimLines L, ClaimHistoryLines H
Query is as follows:
select S.SBSB_ID, M.MEME_NAME,
(CASE L.CLCL_ID WHEN '' THEN H.CLCL_ID ELSE L.CLCL_ID END) AS CLAIM_ID
FROM CMC_CDDL_CL_LINE L, CMC_MEME_MEMBER M LEFT OUTER JOIN CMC_CLDH_DEN_HIST H
ON H.MEME_CK = M.MEME_CK, CMC_SBSB_SUBSC S
WHERE
S.SBSB_ID = '120943270' AND
L.MEME_CK = M.MEME_CK AND
M.SBSB_CK = S.SBSB_CK
This query successfully pulls in the result rows from the ClaimLines L table but no results from the History table are shown. I'm not sure how to do this, any sql experts out there that can help would be great. -Thanks!
CMC_CDDL_CL_LINE L, CMC_MEME_MEMBER M LEFT OUTER JOIN CMC_CLDH_DEN_HIST H
don't mix obsolete implied join syntax with left join. They don't play well together. Use the correct ANSII standard join syntax. Infact stop using the obsolete syntax altogether.
This was a very silly mistake on my part. I neglected to think of using a UNION which solved my problem and allowed me to pull from both places into a single results set without creating massive duplicate rows. Glad someone pointed out the proper way to write sql using ANSII standards.
select S.SBSB_ID, M.MEME_NAME,
L.CLCL_ID AS CLAIM_ID
FROM
CMC_SBSB_SUBSC S INNER JOIN CMC_MEME_MEMBER M ON S.SBSB_CK = M.SBSB_CK
INNER JOIN CMC_CDDL_CL_LINE L ON L.MEME_CK = M.MEME_CK
WHERE
S.SBSB_ID = '120943270'
UNION
select S.SBSB_ID, M.MEME_NAME,
H.CLCL_ID AS CLAIM_ID
FROM
CMC_SBSB_SUBSC S INNER JOIN CMC_MEME_MEMBER M ON S.SBSB_CK = M.SBSB_CK
INNER JOIN CMC_CLDH_DEN_HIST H ON H.MEME_CK = M.MEME_CK
WHERE
S.SBSB_ID = '120943270'