Oracle Table alias in join - sql

is it possible to use the table alias in an ON-Statement?
SQL Statement:
SELECT XMLELEMENT("row", XMLATTRIBUTES(rownum as "order"),
(
SELECT
XMLAGG(XMLELEMENT("attribute",XMLATTRIBUTES(z as "identifier") ) )
FROM b
LEFT JOIN c
ON c.ID = b.cID
AND c.example = table_alias.example
)
)
FROM
(
SELECT example FROM x ORDER BY y
) table_alias
I'm getting the error that table_alias.example is an invalid identifier.
If I move the c.example = table_alias.example into a WHERE Statement it works, but of course I'll get the wrong result.
Anyone have an idea?
TY
frgtv10

try this
SELECT XMLELEMENT("row", XMLATTRIBUTES(rownum as "order"),
( SELECT XMLAGG(XMLELEMENT("attribute"),XMLATTRIBUTES(z as "identifier") ) )
FROM b, c, x
where c.ID = b.cID(+) AND c.example = x.example
)
) from dual

Related

MariaDB / MySQL CTE Raw SQL ambiguous error

I have this RAWSQL query
with
group as (
select * from groups where id = ?
),
attributes as (
select JSON_ARRAYAGG(
JSON_OBJECT('id', a.id,'name', a.name ))
from attributes a
join groups g on g.id = ?
join attribute_group ag on ag.group_id = g.id
and ag.attribute_id = a.id
),
templates as (
select JSON_ARRAYAGG(
JSON_OBJECT('id', t.id,'name', t.name))
from templates t
join groups g on g.id = ?
join group_template gt on gt.group_id = g.id
and gt.template_id = t.id
)
select *,
(select cast(count(*) as char) from attribute_group where group_id = ? ) groups_count,
(select * from groups) groups,
(select cast(count(*) as char) from group_template where group_id = ? ) templates_count,
from group
I have this error
Query 1 ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'group as (
The documentation advises to not use reserved words like group and groups. They are reserved characters and should only be used for things like the GROUP BY statement:
GROUP (R)
GROUPING (R); added in 8.0.1 (reserved)
GROUPS (R); added in 8.0.2 (reserved)
Outside of that, I noticed a few syntax errors:
If you have a table named GROUP, which it looks like you do, you
can escape the reserved word by using back ticks `` or double quotes "" (I.e. `group`, "group").
Remove the comma , after templates_count,.
Replace ? with a valid id column value (I used 1 below).
Like so:
with
`group` as (
select * from `groups` where id = 1
),
attributes as (
select JSON_ARRAYAGG(
JSON_OBJECT('id', a.id,'name', a.name ))
from attributes a
join `groups` g on g.id = 1
join attribute_group ag on ag.group_id = g.id
and ag.attribute_id = a.id
),
templates as (
select JSON_ARRAYAGG(
JSON_OBJECT('id', t.id,'name', t.name))
from templates t
join `groups` g on g.id = 1
join group_template gt on gt.group_id = g.id
and gt.template_id = t.id
)
select *,
(select cast(count(*) as char) from attribute_group where group_id = 1 ) groups_count,
(select * from `groups`) `groups`,
(select cast(count(*) as char) from group_template where group_id = 1 ) templates_count
from `group`

Update statement with join on Oracle

I have this query but it's not working. Can you tell me the solution?
update temp_msisdn_saldo
set saldo=(
select sum(saldo) from (
select a.msisdn as mdn, a.saldo from temp_msisdn_saldo a
union all
select b.mdn as mdn, b.saldo from temp_msisdn_saldo_yesterday b
) z
)
where msisdn=z.mdn
You can rewrite it as :
update temp_msisdn_saldo
set saldo = ( select sum(saldo)
from (select a.msisdn as mdn, a.saldo
from temp_msisdn_saldo a
union all
select b.mdn as mdn, b.saldo
from temp_msisdn_saldo_yesterday b
) z
where z.mdn = temp_msisdn_saldo.msisdn
);
Same you can use CTE :
with cte as (
<your query here>
)
update temp_msisdn_saldo
set saldo = (select sum(c.saldo) from cte c where c.mdn = temp_msisdn_saldo.msisdn);

SQL: Missing right parenthesis in nested SELECT

My code looks like this:
...
LEFT JOIN
(
SELECT *
FROM REI_COUNTRY_CURRENCY T_CC
WHERE T_CC.AS_FROM_DATE =
(
SELECT MAX(T2_CC.AS_FROM_DATE)
FROM REI_COUNTRY_CURRENCY T2_CC
WHERE T2_CC.COUNTRY_ID = T_CC.COUNTRY_ID
) T
) CC
ON C.COUNTRY_ID = CC.COUNTRY_ID
...
I can't see why it would say "missing right parenthesis".
All parentheses are paired.
Aliases are not necessary/allowed on sub-queries:
LEFT JOIN
(
SELECT *
FROM REI_COUNTRY_CURRENCY T_CC
WHERE T_CC.AS_FROM_DATE =
(
SELECT MAX(T2_CC.AS_FROM_DATE)
FROM REI_COUNTRY_CURRENCY T2_CC
WHERE T2_CC.COUNTRY_ID = T_CC.COUNTRY_ID
) -- Remove the T from this line
) CC
ON C.COUNTRY_ID = CC.COUNTRY_ID
Or, to get rid of the correlated sub-query:
LEFT JOIN
(
SELECT *
FROM (
SELECT T_CC.*,
RANK() OVER (
PARTITION BY Country_ID
ORDER BY AS_FROM_DATE DESC
) AS rn
FROM REI_COUNTRY_CURRENCY T_CC
)
WHERE rn = 1
) CC
ON C.COUNTRY_ID = CC.COUNTRY_ID

Alternative solution for below SQL Query ,TableMasterID NOT IN take so much time

Need alternative solution for below SQL Query ,TableMasterID NOT IN take so much time, If i remove AND TableMasterID NOT IN
(SELECT DISTINCT c.TableMasterID
FROM ComFinalDataBS as C
WHERE C.ComFileID IN
(SELECT Number FROM fn_SplitInt(#ComFileID,','))) text from below query then getting result in 20 seconds otherwise result getting arround 4 minus.
SELECT A.SubTitleId,TableMasterID from SubTitle as A JOIN ComTableMaster as B ON a.SubTitle = b.TblName AND TableMasterID NOT IN (SELECT DISTINCT c.TableMasterID
FROM ComFinalDataBS as C
WHERE C.ComFileID IN
(SELECT Number FROM fn_SplitInt(#ComFileID,','))) AND B.TableMasterID IN
(SELECT DISTINCT d.TableMasterID
FROM ComData as D
WHERE D.ComFileID IN
(SELECT Number FROM fn_SplitInt(#ComFileID,','))) ORDER BY A.MainTitleID
SELECT A.SubTitleId ,
TableMasterID
FROM SubTitle AS A
JOIN ComTableMaster AS B ON A.SubTitle = B.TblName
WHERE NOT EXISTS ( SELECT 1
FROM ComFinalDataBS C
WHERE TableMasterID = C.TableMasterID
AND C.ComFileID IN (
SELECT Number
FROM MEFCampus..fn_SplitInt(#ComFileID, ',') ) )
AND NOT EXISTS ( SELECT 1
FROM ComData D
WHERE TableMasterID = D.TableMasterID
AND D.ComFileID IN (
SELECT Number
FROM MEFCampus..fn_SplitInt(#ComFileID,
',') ) )
AND B.IsDeleted = 0
ORDER BY MainTitleID
Have you tried storing the result from the fn_split_string() into an indexed temp-table first? It should help the Query Optimizer a lot.
SELECT DISTINCT Number
INTO #ComFileID
FROM dbo.fn_SplitInt(#ComFileID,',')
CREATE UNIQUE CLUSTERED INDEX uq0_ComFileID ON #ComFileID (Number) WITH (FILLFACTOR = 100)
SELECT A.SubTitleId,TableMasterID
FROM SubTitle as A
JOIN ComTableMaster as B
ON a.SubTitle = b.TblName
/*
AND B.TableMasterID NOT IN (SELECT DISTINCT c.TableMasterID
FROM ComFinalDataBS as C
JOIN #ComFileID CFI
ON CFI.Number = C.ComFileID )
*/
AND NOT EXISTS ( SELECT *
FROM ComFinalDataBS as C
JOIN #ComFileID CFI
ON CFI.Number = C.ComFileID
WHERE c.TableMasterID = B.TableMasterID )
/*
AND B.TableMasterID IN (SELECT DISTINCT d.TableMasterID
FROM ComData as D
JOIN #ComFileID CFI
ON CFI.Number = D.ComFileID
*/
AND EXISTS ( SELECT *
FROM ComData as D
JOIN #ComFileID CFI
ON CFI.Number = D.ComFileID
WHERE D.TableMasterID = B.TableMasterID )
ORDER BY A.MainTitleID

SQL for columns A, B, C: group by A, compute share of B equals C for each A

Database is Oracle. I have a single table with three columns, A, B and C.
A is a string column
B is an int column
C is an int column
I need an SQL select that groups on A and returns the share (in percent) where B = C = [particular int value] for each value of A.
Something like
SELECT A, percentBEqC
...
GROUP ON A
SELECT A
, COUNT( CASE WHEN B = C AND C = 256
THEN 1
END
)
/ COUNT(*) AS percentBEqC
FROM YourTable
GROUP BY A
You may want to check if B = 256 AND C = 256 has better performance.
Another way for your problem would be:
SELECT ta.A
, COALESCE(cnt,0) / cntAll AS percentBEqC
FROM
( SELECT A
, COUNT(*) AS cntAll
FROM YourTable
GROUP BY A
) ta
LEFT JOIN
( SELECT A
, COUNT(*) AS cnt
FROM YourTable
WHERE B = 256 AND C = 256
GROUP BY A
) ts
ON ts.A = ta.A
Another way:
..once the syntax is correct ;/
SELECT A, (COUNT(*) / (SELECT COUNT(*) FROM mytbl b WHERE b.A = a.A)) AS percentBEqC
FROM mytbl a
WHERE B = particular_value
AND C = particular_value
GROUP BY A;
Returns only rows where percentBEqC > 0,