How to create a calculated column by comparing string values from another column in Tibco spot fire - tibco

can some one please help me to create a calculated
column as explained below?
consider the table
col1 | col2 | col3
1 | x | ER
1 | x | IG
1 | x | C
1 | y | ER
1 | y | ER
2 | y | IG
2 | y | C
2 | y | ER
2 | z | ER
2 | z | IG
I need a calculated column which says 'success' if there exists at least one 'C' on col3 for group of col1 and col2, else 'fail'.
so my new table must look like:
col1 | col2 | col3 | calculated_col
1 | x | ER | success
1 | x | IG | success
1 | x | C | success
1 | y | ER | fail
1 | y | ER | fail
2 | y | IG | success
2 | y | C | success
2 | y | ER | success
2 | z | ER | fail
2 | z | IG | fail
that is:
for the combination of 1 and 'x' from col1 and col2 respectively there is at leat one 'c' at col3, so expression result is 'success'
for the combination of 1 and 'y' from col1 and col2 respectively there is no 'c' at col3, so the expression result is 'fail'
for the combination of 2 and 'y' from col1 and col2 respectively there is at least one 'c' at col3, so expression result is 'success'
for the combination of 2 and 'z' from col1 and col2 respectively there is no 'c' at col3, so the expression result is 'fail'

you can use the Intersect OVER function to gather values in cells according to a hierarchy you define (in this case, col1>col2).
the following expression produces your desired results:
If(
Find("C", UniqueConcatenate([col3]) OVER (Intersect([col1], [col2]))) > 0,
"success","fail"
)
it's not particularly robust, however: if you have any other values in col3 that contain "C", this expression will evaluate to "success"!

Related

Lag and Lead to next month

TABLE: HIST
CUSTOMER MONTH PLAN
1 1 A
1 2 B
1 2 C
1 3 D
If I query:
select h.*, lead(plan) over (partition by customer order by month) np from HIST h
I get:
CUSTOMER MONTH PLAN np
1 1 A B
1 2 B C
1 2 C D
1 3 D (null)
But I wanted
CUSTOMER MONTH PLAN np
1 1 A B
1 2 B D
1 2 C D
1 3 D (null)
Reason being, next month to 2 is 3, with D. I'm guessing partition by customer order by month doesn't work the way I thought.
Is there a way to achieve this in Oracle 12c?
One way to do it is to use RANGE partitioning with the MIN analytic function. Like this:
select h.*,
min(plan) over
(partition by customer
order by month
range between 1 following and 1 following) np
from HIST h;
+----------+-------+------+----+
| CUSTOMER | MONTH | PLAN | NP |
+----------+-------+------+----+
| 1 | 1 | A | B |
| 1 | 2 | B | D |
| 1 | 2 | C | D |
| 1 | 3 | D | |
+----------+-------+------+----+
When you use RANGE partitioning, you are telling Oracle to make the windows based on the values of the column you are ordering by rather than making the windows based on the rows.
So, e.g.,
ROWS BETWEEN 1 following and 1 following
... will make a window containing the next row.
RANGE BETWEEN 1 following and 1 following
... will make a window containing all the rows having the next value for month.
UPDATE
If it is possible that some values for MONTH might be skipped for a given customer, you can use this variant:
select h.*,
first_value(plan) over
(partition by customer
order by month
range between 1 following and unbounded following) np
from h
+----------+-------+------+----+
| CUSTOMER | MONTH | PLAN | NP |
+----------+-------+------+----+
| 1 | 1 | A | B |
| 1 | 3 | B | D |
| 1 | 3 | C | D |
| 1 | 4 | D | |
+----------+-------+------+----+
You can use LAG/LEAD twice. The first time to check for duplicate months and to set the value to NULL in those months and the second time use IGNORE NULLS to get the next monthly value.
It has the additional benefit that if months are skipped then it will still find the next value.
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE HIST ( CUSTOMER, MONTH, PLAN ) AS
SELECT 1, 1, 'A' FROM DUAL UNION ALL
SELECT 1, 2, 'B' FROM DUAL UNION ALL
SELECT 1, 2, 'C' FROM DUAL UNION ALL
SELECT 1, 3, 'D' FROM DUAL UNION ALL
SELECT 2, 1, 'E' FROM DUAL UNION ALL
SELECT 2, 1, 'F' FROM DUAL UNION ALL
SELECT 2, 3, 'G' FROM DUAL UNION ALL
SELECT 2, 5, 'H' FROM DUAL;
Query 1:
SELECT CUSTOMER,
MONTH,
PLAN,
LEAD( np ) IGNORE NULLS OVER ( PARTITION BY CUSTOMER ORDER BY MONTH, PLAN, ROWNUM ) AS np
FROM (
SELECT h.*,
CASE MONTH
WHEN LAG( MONTH ) OVER ( PARTITION BY CUSTOMER ORDER BY MONTH, PLAN, ROWNUM )
THEN NULL
ELSE PLAN
END AS np
FROM hist h
)
Results:
| CUSTOMER | MONTH | PLAN | NP |
|----------|-------|------|--------|
| 1 | 1 | A | B |
| 1 | 2 | B | D |
| 1 | 2 | C | D |
| 1 | 3 | D | (null) |
| 2 | 1 | E | G |
| 2 | 1 | F | G |
| 2 | 3 | G | H |
| 2 | 5 | H | (null) |
Just so that it is listed here as an option for Oracle 12c (onward), you can use an apply operator for this style of problem
select
h.customer, h.month, h.plan, oa.np
from hist h
outer apply (
select
h2.plan as np
from hist h2
where h.customer = h.customer
and h2.month > h.month
order by month
fetch first 1 rows only
) oa
order by
h.customer, h.month, h.plan
I don't know of any Oracle 12c public fiddles so, an example in SQL Server can be found here: http://sqlfiddle.com/#!18/cd95e/1
| customer | month | plan | np |
|----------|-------|------|--------|
| 1 | 1 | A | C |
| 1 | 2 | B | D |
| 1 | 2 | C | D |
| 1 | 3 | D | (null) |

oracle - querying NULL values in unpivot query

I want to fetch records from oracle DB where column value is NULL. Also i am using unpivot in my query. Somehow NULL values are not getting selected because of unpivot keyword. Can you please help me about how to get rows for the same when using unpivot.
EDIT:
SELECT a.emp_id, a.emp_dept, b.emp_location
FROM employee a,
location b UNPIVOT (emp_id
FOR dummy_id
IN (emp_id AS 'EMP_ID', last_date AS 'LAST_DATE'))
WHERE emp_id = 123 AND b.emp_loc_id = 'india' AND b.location IS NULL;
Use UNPIVOT INCLUDE NULLS:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE test ( id, a, b, c, d ) AS
SELECT 1, 1, 2, 3, 4 FROM DUAL UNION ALL
SELECT 2, 1, NULL, 3, NULL FROM DUAL;
Query 1:
SELECT *
FROM test
UNPIVOT INCLUDE NULLS ( value FOR name IN ( a, b, c, d ) )
Results:
| ID | NAME | VALUE |
|----|------|--------|
| 1 | A | 1 |
| 1 | B | 2 |
| 1 | C | 3 |
| 1 | D | 4 |
| 2 | A | 1 |
| 2 | B | (null) |
| 2 | C | 3 |
| 2 | D | (null) |

How to fill same value with child row

In Oracle, i want to fill child to lowest parent value.
that is query and result
query :
SELECT col1,col2 FROM DATA
result :
+-----------+------+
| col1 | col2 |
+-----------+------+
| 001 | a |
| 001001 | b |
| 001002 | c |
| 001003 | d |
| 001003001 | e |
| 001003002 | f |
| 002 | g |
| 003 | h |
| 003001 | i |
| 003002 | j |
+-----------+------+
col1 is key. and child index have parent index.
i want to make this result
+------+------+------+------+
| col1 | col2 | col3 | col4 |
+------+------+------+------+
| a | b | b | b |
| a | c | c | c |
| a | d | e | e |
| a | d | f | f |
| g | g | g | g |
| h | i | i | i |
| h | j | j | j |
+------+------+------+------+
if parent have no child, child columns fill to parent.
how can i make this result?...
thank you.
One way to do this:
select c1, coalesce(c2, c1) c2, coalesce(c3, c2, c1) c3, coalesce(c4, c3, c2, c1) c4
from (select substr(path, 2, 1) c1, substr(path, 4, 1) c2,
substr(path, 6, 1) c3, substr(path, 8, 1) c4
from (select sys_connect_by_path(col2, ' ') path
from data
where connect_by_isleaf = 1
connect by substr(col1, 1, length(prior col1)) = prior col1
and length(prior col1) + 3 = length(col1)
start with length(col1) = 3 ) )
Assuming that values in col2 are 1-char long You can do it like above. Otherwise you have to change substr(path, ..., ...) using instr() or regular expressions.
The inner query is hierarchical where I'm selecting only whole path from leaf rows. Outer queries puts data into particular columns dealing with null values.
If You work on Oracle 11g or above You can probably achieve this in more elegant way using Recursive Subquery Factoring.
Test data and output:
create table data (col1 varchar2(10), col2 varchar2(1));
insert into data values ('001', 'a');
insert into data values ('001001', 'b');
insert into data values ('001002', 'c');
insert into data values ('001003', 'd');
insert into data values ('001003001', 'e');
insert into data values ('001003002', 'f');
insert into data values ('002', 'g');
insert into data values ('003', 'h');
insert into data values ('003001', 'i');
insert into data values ('003002', 'j');
C1 C2 C3 C4
-- -- -- --
a b b b
a c c c
a d e e
a d f f
g g g g
h i i i
h j j j
7 rows selected

LINQ to get distinct column value with count of a string

I have below data in datatable -
Col1 Col2
-----------------------
Pramod | In
Pramod | In
Pramod | Out
Pramod | In
Pramod | In
Pramod | Out
Pankaj | In
Pankaj | In
Pankaj | Out
Abhi | In
Abhi | In
Abhi | Out
I want below output using LINQ,
Col1 | In | Out
------------------
Pramod | 4 | 2
Pankaj | 2 | 1
Abhi | 2 | 1
Please help
Group rows by value of Col1 and then calculate number of In and Out values in each group:
from r in table.AsEnumerable()
group r by r.Field<string>("Col1") into g
select new {
Col1 = g.Key,
In = g.Count(r => r.Field<string>("Col2") == "In"),
Out = g.Count(r => r.Field<string>("Col2") == "Out")
}

Joining tables with same column names - ORACLE

I am using Oracle.
I am currently working one 2 tables which both have the same column names. Is there any way in which I can combine the 2 tables together as they are?
Simple example to show what I mean:
TABLE 1:
| COLUMN 1 | COLUMN 2 | COLUMN 3 |
----------------------------------------
| a | 1 | w |
| b | 2 | x |
TABLE 2:
| COLUMN 1 | COLUMN 2 | COLUMN 3 |
----------------------------------------
| c | 3 | y |
| d | 4 | z |
RESULT THAT I WANT:
| COLUMN 1 | COLUMN 2 | COLUMN 3 |
----------------------------------------
| a | 1 | w |
| b | 2 | x |
| c | 3 | y |
| d | 4 | z |
Any help would be greatly appreciated. Thank you in advance!
You can use the union set operator to get the result of two queries as a single result set:
select column1, column2, column3
from table1
union all
select column1, column2, column3
from table2
union on its own implicitly removes duplicates; union all preserves them. More info here.
The column names don't need to be the same, you just need the same number of columns with the same datatpes, in the same order.
(This is not what is usually meant by a join, so the title of your question is a bit misleading; I'm basing this on the example data and output you showed.)

Resources