Using Row Pivot Together - oracle

My Raw Query Is
select element1_name, element1_value, element2_name, element2_value
from reports r
I Want Convert element_name,element_value Rows To Columns So Write This Query
select *
from (select *
from (select element1_name,
element1_value,
element2_name,
element2_value
from reports r)
pivot(max(element1_value) as one
for element1_name in('C' as C, 'Si' as SI, 'P' as P)))
pivot(max(element2_value) as tow
for element2_name in('C' as C, 'Si' as SI, 'P' as P))
There Is A Way That Write Two Pivot Together Without Two Sub Query Like this
Select * (...) pivot element1,pivot element2
Question:How to optimize this query?

You can try below query -
select *
from (select element1_name,
element1_value,
element2_name,
element2_value
from reports) AS R
pivot(max(element1_value) for element1_name in('C' as C, 'Si' as SI, 'P' as P)) as PV1
pivot(max(element2_value) for element2_name in('C' as C, 'Si' as SI, 'P' as P)) as PV2;

Related

Why maxMerge() gives different results than max() of sumMerge()?

The whole point is to get peaks per period (e.g. 5m peaks) for value that accumulates. So it needs to be summed per period and then the peak (maximum) can be found in those sums. (select max(v) from (select sum(v) from t group by a1, a2))
I have a base table t.
Data are inserted into t, consider two attributes (time t1 and some string a2) and one numeric value.
Value accumulates so it needs to be summed to get the total volume over certain period. Example of rows inserted:
t1 | a2 | v
----------------
date1 | b | 1
date2 | c | 20
I'm using a MV to compute sumState() and from that I get peaks using sumMerge() and then max().
I need it only for max values so I was wondering I could use maxState() directly.
So this is what I do now: I use MV that computes a 5m sum and from that I read max()
CREATE TABLE IF NOT EXISTS sums_table ON CLUSTER '{cluster}' (
t1 DateTime,
a2 String,
v AggregateFunction(sum, UInt32)
)
ENGINE = ReplicatedAggregatingMergeTree(
'...',
'{replica}'
)
PARTITION BY toDate(t1)
ORDER BY (a2, t1)
PRIMARY KEY (a2);
CREATE MATERIALIZED VIEW IF NOT EXISTS mv_a
ON CLUSTER '{cluster}'
TO sums_table
AS
SELECT toStartOfFiveMinute(t1) AS t1, a2,
sumState(toUInt32(v)) AS v
FROM t
GROUP BY t1, a2
from that I'm able to read max of 5m sum for a2 using
SELECT
a2,
max(sum) AS max
FROM (
SELECT
t1,
a2,
sumMerge(v) AS sum
FROM sums_table
WHERE t1 BETWEEN :fromDateTime AND :toDateTime
GROUP BY t1, a2
)
GROUP BY a2
ORDER BY max DESC
That works perfectly.
So I wanted to achieve the same using maxState and maxMerge():
CREATE TABLE IF NOT EXISTS max_table ON CLUSTER '{cluster}' (
t1 DateTime,
a2 String,
max_v AggregateFunction(max, UInt32)
)
ENGINE = ReplicatedAggregatingMergeTree(
'...',
'{replica}'
)
PARTITION BY toDate(t1)
ORDER BY (a2, t1)
PRIMARY KEY (a2)
CREATE MATERIALIZED VIEW IF NOT EXISTS mv_b
ON CLUSTER '{cluster}'
TO max_table
AS
SELECT
t1,
a2
maxState(v) AS max_v
FROM (
SELECT
toStartOfFiveMinute(t1) AS t1,
a2,
toUInt32(sum(v)) AS v
FROM t
GROUP BY t1, a2
)
GROUP BY t1, a2
and I thought if I get a max per time (t1) and a2, and then select max of that per a2, I'd get the maximum value for each a2, but I'm getting totally different max values using this query compared to the max of sums mentioned above.
SELECT
a2,
max(max) AS max
FROM (
SELECT
t1,
a2,
maxMerge(v) AS max
FROM max_table
WHERE t1 BETWEEN :fromDateTime AND :toDateTime
GROUP BY t1, a2
) maxs_per_time_and_a2
GROUP BY a2
What did I do wrong? Do I get MVs wrong? Is it possible to use maxState with maxMerge for 2+ attributes to compute max over a longer period, let's say year?
SELECT
t1,
a2
maxState(v) AS max_v
FROM (
SELECT
toStartOfFiveMinute(t1) AS t1,
a2,
toUInt32(sum(v)) AS v
FROM t
GROUP BY t1, a2
)
GROUP BY t1, a2
This is incorrect. And impossible.
Because MV is an insert trigger. It never reads REAL table t.
You are getting max from sum of rows in insert buffer.
If you insert 1 row with v=10. You will get max_v = 10. MatView does not "know" that a previous insert has added some rows, their sum is not taken into account.

Can multiple joins exist in a single sql statement

A good example of this would be
SELECT * FROM A WHERE M LEFT OUTER JOIN N, P LEFT OUTER JOIN Q..

How to add two outputs or query and get a one consolidated result for below queries

1.
select M.MASTER_REF, case B.Type when 450 Then 'RED'
when 420 Then 'RVL'
END Note_Type, B.CODE, B.NOTE_TEXT, (E.REFNO_PFIX || ''|| E.REFNO_SERL)AS Event_Ref, B.CREATED_AT, B.ACTIVE
from Note B, MASTER M, BASEEVENT E, TIDataItem N
where B.KEY97=N.KEY97 and N.MASTER_KEY=M.KEY97 and E.KEY97 = B.NOTE_EVENT
and M.EXEMPLAR in ('8806648499869051681','8806648499869023154','8806648499869054292','8806648499869006425')
and M.STATUS in ('LIV','EXP')
and B.Code not in ('Migration')
order by M.Master_Ref Asc, B.CREATED_AT desc
2.
select M.MASTER_REF, case B.Type when 450 Then 'RED'
when 420 Then 'RVL'
END Note_Type, B.CODE, B.NOTE_TEXT, B.Note_Event AS Event_Ref, B.CREATED_AT, B.ACTIVE
from Note B, MASTER M, TIDataItem N
where B.KEY97=N.KEY97 and N.MASTER_KEY=M.KEY97 and B.NOTE_EVENT is null
and M.EXEMPLAR in ('8806648499869051681','8806648499869023154','8806648499869054292','8806648499869006425')
and M.STATUS in ('LIV','EXP')
and B.Code not in ('Migration')
order by M.Master_Ref Asc, B.CREATED_AT desc
Use UNION ALL to add similar result sets together. Column order and data types must match between each set. The ORDER BY should be at the last SELECT only and can reference only column alias.
select
M.MASTER_REF,
case B.Type
when 450 Then 'RED'
when 420 Then 'RVL' END Note_Type,
B.CODE,
B.NOTE_TEXT,
(E.REFNO_PFIX || ''|| E.REFNO_SERL) AS Event_Ref,
B.CREATED_AT,
B.ACTIVE
from
Note B,
MASTER M,
BASEEVENT E,
TIDataItem N
where
B.KEY97=N.KEY97 and
N.MASTER_KEY=M.KEY97 and
E.KEY97 = B.NOTE_EVENT and
M.EXEMPLAR in ('8806648499869051681','8806648499869023154','8806648499869054292','8806648499869006425') and
M.STATUS in ('LIV','EXP') and
B.Code not in ('Migration')
UNION ALL
select
M.MASTER_REF,
case B.Type
when 450 Then 'RED'
when 420 Then 'RVL' END Note_Type,
B.CODE,
B.NOTE_TEXT,
TO_CHAR(B.Note_Event) AS Event_Ref,
B.CREATED_AT,
B.ACTIVE
from
Note B,
MASTER M,
TIDataItem N
where
B.KEY97=N.KEY97 and
N.MASTER_KEY=M.KEY97 and
B.NOTE_EVENT is null and
M.EXEMPLAR in ('8806648499869051681','8806648499869023154','8806648499869054292','8806648499869006425') and
M.STATUS in ('LIV','EXP') and
B.Code not in ('Migration')
order by
Master_Ref Asc,
CREATED_AT desc
I strongly suggest you avoid using old join syntax as it makes the code less readable (use explicit INNER or LEFT JOIN with the proper ON clause):
Change:
from
Note B,
MASTER M,
TIDataItem N
where
B.KEY97=N.KEY97 and
N.MASTER_KEY=M.KEY97
For:
FROM
Note B
INNER JOIN TIDataItem N ON B.KEY97 = N.KEY97
INNER JOIN MASTER M ON N.MASTER_KEY = M.KEY97

hive select count based on average of count

Hi I am trying to work on finding the count which is higher than average using the below hive statement
Select x, Count(x) as y from data
group by x
Having Count(x) >= (select Avg(z.count1) as aveg
from (select x, Count(x) as count1 from data group by x ) z) ;
I am receiving error as ParseException line 1:87 cannot recognize input near 'Select' 'Avg' '(' in expression specification
select x
,cnt_x
from (select x
,count(x) as cnt_x
,avg (count(x)) over () as avg_cnt_x
from data
group by x
) t
where cnt_x >= avg_cnt_x

Oracle Left outer join

SELECT
a,
last_note_user,
c,
d,
iso_src
FROM
X
CROSS JOIN Y
CROSS JOIN Z
LEFT OUTER JOIN W
ON W.last_note_user = Z.userid
AND W.user_ten = Y.iso_src
The above ANSI code fetch me 107 records,When I giving the same query without ANSI code it is fetching 875 records.The non ANSI query is below:
SELECT
a,
last_note_user,
c,
d,
iso_src
FROM
X,
Y,
Z,
W
WHERE
W.last_note_user = Z.userid(+)
AND W.user_ten = Y.iso_src(+)
why there is difference in the two query with ANSI and without ANSI standards??
By answering the above query please help me out!!!
Your old-style query has the (+) symbols on the wrong side of the predicate. It should be:
SELECT
a,
last_note_user,
c,
d,
iso_src
FROM
X,
Y,
Z,
W
WHERE
W.last_note_user (+) = Z.userid
AND W.user_ten (+) = Y.iso_src
But I wouldn't use the old-style syntax any more really.
OUTER JOINS with old ANSI-syntax are ambiguous, so who knows what the query optimizer understands with this.
If the first SQL is producing the right rows, forget about the ANSI version and move on.

Resources