I have a table say t1
I have columns A1,A2,a3,a4,a5
I need output like
A -column name
A1-value in a1
A2-value in a2
A3
A4
Looks like UNION.
select a1 as a from t1 union all
select a2 from t1 union all
select a3 from t1 ...
Related
Just like Oracle continues to follow a path beyond a cyclical loop when the cycle occurs at the top node (root node connected right back to root node), is there any way to do the same with in between cycle.
Like if i have some data like below
create table t1 ( c1 varchar2(2), c2 varchar2(2));
insert into t1 values ('A', 'B');
insert into t1 values ('B', 'C');
insert into t1 values ('C', '**A**');
and execute below query:
select * from (
select distinct
connect_by_root c1 as c3,
c1,
c2
from t1
connect by nocycle c1 = prior c2
) where c3='A';
It will give me this results
c3 c1 c2
A A B
A B C
**A** **C** **A**
It gives me the root looped valued. But if i have data like below.
create table t2 ( c1 varchar2(2), c2 varchar2(2));
insert into t2 values ('A', 'B');
insert into t2 values ('B', 'C');
insert into t2 values ('C', '**B**');
select * from (
select distinct
connect_by_root c1 as c3,
c1,
c2
from t2
connect by nocycle c1 = prior c2
) where c3='A';
this gives me
c3 c1 c2
A A B
A B C
But i need third row also that is A C B.
So wondering if this could be done?
You can use a recursive sub-query factoring clause:
WITH rsqfc ( c3, c1, c2 ) AS (
SELECT c1, c1, c2
FROM t2
WHERE c1 = 'A'
UNION ALL
SELECT r.c3, t.c1, t.c2
FROM t2 t
INNER JOIN rsqfc r
ON ( t.c1 = r.c2 )
)
CYCLE c1, c2 SET is_cycle TO 1 DEFAULT 0
SELECT c3, c1, c2
FROM rsqfc
WHERE is_cycle = 0;
Which, for your sample data:
create table t2 ( c1, c2 ) AS
SELECT 'A', 'B' FROM DUAL UNION ALL
SELECT 'B', 'C' FROM DUAL UNION ALL
SELECT 'C', 'B' FROM DUAL;
Outputs:
C3 | C1 | C2
:- | :- | :-
A | A | B
A | B | C
A | C | B
db<>fiddle here
There are five colums.
How to get average of the row (not column) and
the average should be made with minimum and maximum excluded.
If there are duplicate maximum or(and) minimum, how to exlude them all?
The result of my data should be like this.
Average_MIN_MAX_excluded
-------------------------
3.33333333
5.33333333
My data set is as below;
WITH DATAA AS
(SELECT 3 c1,5 c2,4 c3,3 c4 ,1 c5 FROM DUAL
UNION
SELECT 1 c1,3 c2,6 c3,9 c4 ,7 c5 FROM DUAL)
SELECT c1, c2, c3, c4, c5 FROM DATAA;
select ((c1 + c2 + c3 + c4 + c5) -
greatest( c1, c2, c3, c4, c5 ) -
least( c1, c2, c3, c4, c5 ))/ 3
from DATAA
would be one way. Here's a liveSQL link
It is a good place to use LATERAL JOIN aka CROSS APPLY:
SELECT *
FROM t
CROSS APPLY (
SELECT AVG(c) AS Average_MIN_MAX_excluded
FROM (
SELECT c, ROW_NUMBER() OVER(ORDER BY c) rn
FROM (
SELECT c1 c FROM dual UNION ALL
SELECT c2 FROM dual UNION ALL
SELECT c3 FROM dual UNION ALL
SELECT c4 FROM dual UNION ALL
SELECT c5 FROM dual)
)
WHERE rn NOT IN (1,5)
) s;
This method allows to easily exclude 1,2,3 highest/lowest values if necessary.
db<>fiddle demo
I think you can use unpivot and analytical function with group by and average aggregate function as following:
WITH DATAA AS
(
SELECT 3 c1,5 c2,4 c3,3 c4 ,1 c5 FROM DUAL
UNION
-- case with same value at min for two columns
SELECT 1 c1,5 c2,4 c3,3 c4 ,1 c5 FROM DUAL
UNION
SELECT 1 c1,3 c2,6 c3,9 c4 ,7 c5 FROM DUAL)
-- your query starts from here
select rn, avg(val) from
(select rn, val,
max(val) over (partition by rn) maxval,
min(val) over (partition by rn) minval
from
(SELECT rownum rn, c1, c2, c3, c4, c5
FROM DATAA)
unpivot
(val for vals in (c1,c2,c3,c4,c5)))
where val not in (maxval, minval)
group by rn
See db<>fiddle demo.
Cheers!!
I have three tables A, B, C, and I want to randomly take a row from the col_b column of the table B then update it to the table A. Table C is the subtable of Table B, which is used to filter the data of Table B.
Here is my sql statement:
update a a
set a.col_a_b =
(select t.col_b
from (select a1.col_a, b1.col_b, a1.rn_var
-- the number 6 is because I only have 6 rows of data,
-- and the real situation should be the total number of conditions in table b
from (select a0.col_a, TRUNC(dbms_random.value(1, 6)) rn_var
from a a0) a1
left join (select b.col_b, rownum rn
from b b
where exists (select 1
from c c
where b.id = c.col_b_id
and c.col_c = 'c1')) b1
on a1.rn_var = b1.rn) t
where t.col_a = a.col_a);
I found a strange phenomenon:
If I remove a1.rn_var (line from (select a1.col_a, b1.col_b, a1.rn_var), it doesn't work as my expected
On the basis of the above, if I replace exists with left join (or join), the result is the same
If I reomve both a1.rn_var and exists, it will work fine.
I know there may be a better way to implement it, but who can tell me why?
Update:
Actually, it is caused by this sql:
select a1.col_a, b1.col_b -- remove a1.rn_var
from (select a0.col_a, TRUNC(dbms_random.value(1, 6)) rn_var from a a0) a1
left join (select b.col_b, rownum rn
from b b
where exists (select 1
from c c
where b.id = c.col_b_id
and c.col_c = 'c1')) b1
on a1.rn_var = b1.rn
-- this is for better display of results
where a1.col_a = 'a1';
In the above sql, I may get multiple rows of data or column b1.col_b is empty, as shown below:
a1 b1
a1 b2
a1 b4
------------------------------------------------
a1 -- here is null
In addition, each value of column a1.col_a is the same, I mean, if value a1 has multiple rows, then value a2 (and so on) has the same result, like this:
a1 b2
a1 b4
a1 b5
a2 b2
a2 b4
a2 b5
...
You can use a random number and order by that random number to get random records.
I prefer using the following technique:
UPDATE A A
SET
A.COL_A_B = (
SELECT
COL_B
FROM
(
SELECT
COL_B,
TRUNC(DBMS_RANDOM.VALUE(1, COUNT(1) OVER())) RANDOM_NUMBER --GENERATES RANDOM NUMBER
FROM
(
SELECT DISTINCT
B.COL_B -- FETCHING DISTINCT RESULT
FROM
B B
-- EXISTS IS CONVERTED INTO JOIN
JOIN C C ON ( B.ID = C.COL_B_ID
AND C.COL_C = 'c1' )
)
ORDER BY
RANDOM_NUMBER -- ORDERING IS DONE BY RANDOM NUMBER
FETCH FIRST ROWS ONLY -- FETCHING ONLY FIRST ROW FROM ORDERED RECORDS
)
)
Cheers!!
Table A
A1 A2
1 7
2 8
1 9
Table B
A1 B2
1 2
2 3
i want something like this
select A.A1,sum(case when distinct A.A1 then B2),sum(A.A2) from
A,B
where A.A1=B.A1(+)
group by A.A1
After joining my table will be
A1 A2 B2
1 7 2
2 8 3
1 9 2
Resulting Table
A1 A2 B2
1 7+9 2(only once)
2 8 3
how to get sum of B2 when distinct A1 after joining the tables as stated above.
Thanks in advance
Use JOIN and GROUP BY.
Query
SELECT t1.A1, SUM(t1.A2) AS A1, SUM(t2.B2) AS B2
FROM TableA t1
JOIN TableB t2
ON t1.A1 = t2.A1
GROUP BY t1.A1;
Since table_b.a1 is unique, the best way to do this would be to work out the sum of table_a.a2 first to reduce the number of rows you're joining against, and then join to table_b. Then you don't need to worry about summing the distinct table_b.b2 values, which you would otherwise have to do.
WITH table_a AS (SELECT 1 a1, 7 a2 FROM dual UNION ALL
SELECT 2 a1, 8 a2 FROM dual UNION ALL
SELECT 1 a1, 9 a2 FROM dual),
table_b AS (SELECT 1 a1, 2 b2 FROM dual UNION ALL
SELECT 2 a1, 3 b2 FROM dual)
-- end of mimicking your two tables with sample_data in them;
-- see the sql below:
SELECT ta.a1,
ta.a2,
tb.b2
FROM (SELECT a1, SUM(a2) a2
FROM table_a
GROUP BY a1) ta
INNER JOIN table_b tb ON ta.a1 = tb.a1;
A1 A2 B2
---------- ---------- ----------
1 16 2
2 8 3
If you absolutely must join the two tables first (I don't recommend; this is making more work for the database to do), then you could do something like:
WITH table_a AS (SELECT 1 a1, 7 a2 FROM dual UNION ALL
SELECT 2 a1, 8 a2 FROM dual UNION ALL
SELECT 1 a1, 9 a2 FROM dual),
table_b AS (SELECT 1 a1, 2 b2 FROM dual UNION ALL
SELECT 2 a1, 3 b2 FROM dual)
SELECT ta.a1,
SUM(ta.a2) a2,
MAX(tb.b2) b2
FROM table_a ta
INNER JOIN table_b tb ON ta.a1 = tb.a1
GROUP BY ta.a1;
A1 A2 B2
---------- ---------- ----------
1 16 2
2 8 3
Since there can only be one distinct value for table_b.b2 per table_a.a1, we can just pick one of the values to use via MAX (we could have used MIN or SUM(distinct tb.b2) instead, fyi).
i am implementing a tableviewer that is able to sort values depengin on their column order.
e.g. column1-column2-columnX
sorts the rows first on the values of column 1, then column 2, column....
Therefore i want to use a ColumnViewerSorter, especially the method
"int doCompare(Viewer viewer, Object e1, Object e2);"
inside this method i want to sort depending on other Tableviewer Row/Cells for comparison and the difficulty is that JFace tableviewer does the sort in the view only, so i have to "ask" the tableviewer itself for the actual value of e.g. "column 1, row 20"
using the function "viewer.getElementAt(index)" inside "docompare" wold be ok, but inside docompare i do have no reference to the objects e1 and e2 position in the tableviewer.
how could i achieve that?
thanking you very much in advance for helping me
best regards,
Malcom
You could iterate through all items in the table viewer and see where the objects e1 and e2 are, of course.
BUT... and I hope I understand your problem correctly... why do you want to implement multisorting?
Let's say you have 3 columns:
Col1 Col2 Col3
-------------------------
a2 b1 c4
a1 b2 c1
a2 b1 c3
To obtain the sorting order Col1-Col2-Col3, the user can click on Col3, then on Col2, and in the end Col1:
Col1 Col2 _Col3_
-------------------------
a1 b2 c1
a2 b1 c3
a2 b1 c4
Col1 _Col2_ Col3
-------------------------
a2 b1 c3
a2 b1 c4
a1 b2 c1
_Col1_ Col2 Col3
-------------------------
a1 b2 c1
a2 b1 c3
a2 b1 c4
This might not be the best example, but to obtain "multi sorting", the user just has to sort the desired columns in the opposite order.