INFORMIX: a count of each elementname from sub-query of distinct callid and the Max varable value - informix

Here are my tables:
I need to get a count of the elementname for each each callid where the varname equals 'eCounter' and the varvalue is the greatest.
The tables are relational by elementid one (element) to many (elementdetail). I include the format of the actual elementid so you don't assume they are consecutive numbers.
I tried the following code just to get the Max varvalue/elementid for each call, but that did not work out either.
SELECT MAX(a.varvalue) as MAXvarvalue, b.callgui
FROM elementdetail AS a, element AS b
WHERE (a.elementid = b.elementid) AND (a.varname = 'eCounter')
GROUP BY varname, callguid
This is what I need the results to look like.

Using the latest Informix version ( 14.10.XC1 ).
Assuming the following tables:
CREATE TABLE element
(
callid INTEGER,
elementid BIGINT,
elementname CHAR( 20 )
);
CREATE TABLE elementdetail
(
elementid BIGINT,
varname CHAR( 20 ),
varvalue INTEGER
);
Which are populated with your sample data ( OCR to the rescue, you really should post your sample data and tables as text, not images ):
INSERT INTO element VALUES ( 1, 1001901560322810000, 'set_Page1' );
INSERT INTO element VALUES ( 1, 1001921560322810000, 'set_Page5' );
INSERT INTO element VALUES ( 1, 1001181560322820000, 'set_Page4' );
INSERT INTO element VALUES ( 1, 1001021560322820000, 'set_Page3' );
INSERT INTO element VALUES ( 1, 1001331560322830000, 'set_Page6' );
INSERT INTO element VALUES ( 2, 1002281560322920000, 'set_Page1' );
INSERT INTO element VALUES ( 2, 1002301560322920000, 'set_Page5' );
INSERT INTO element VALUES ( 2, 1002881560322940000, 'set_Page4' );
INSERT INTO element VALUES ( 3, 1002271560322950000, 'set_Page1' );
INSERT INTO element VALUES ( 3, 1002951560322970000, 'set_Page4' );
INSERT INTO element VALUES ( 3, 1002231560322980000, 'set_Page6' );
INSERT INTO element VALUES ( 4, 1002781560323000000, 'set_Page1' );
INSERT INTO element VALUES ( 4, 1002891560323020000, 'set_Page5' );
INSERT INTO element VALUES ( 4, 1002391560323040000, 'set_Page4' );
INSERT INTO elementdetail VALUES ( 1001901560322810000, 'eCounter', 0 );
INSERT INTO elementdetail VALUES ( 1001901560322810000, 'other_variables', NULL );
INSERT INTO elementdetail VALUES ( 1001921560322810000, 'eCounter', 1 );
INSERT INTO elementdetail VALUES ( 1001921560322810000, 'other_variables', NULL );
INSERT INTO elementdetail VALUES ( 1001181560322820000, 'eCounter', 2 );
INSERT INTO elementdetail VALUES ( 1001181560322820000, 'other_variables', NULL );
INSERT INTO elementdetail VALUES ( 1001021560322820000, 'eCounter', 4 );
INSERT INTO elementdetail VALUES ( 1001021560322820000, 'other_variables', NULL );
INSERT INTO elementdetail VALUES ( 1001331560322830000, 'eCounter', 5 );
INSERT INTO elementdetail VALUES ( 1001331560322830000, 'other_variables', NULL );
INSERT INTO elementdetail VALUES ( 1002281560322920000, 'eCounter', 0 );
INSERT INTO elementdetail VALUES ( 1002281560322920000, 'other_variables', NULL );
INSERT INTO elementdetail VALUES ( 1002301560322920000, 'eCounter', 1 );
INSERT INTO elementdetail VALUES ( 1002301560322920000, 'other_variables', NULL );
INSERT INTO elementdetail VALUES ( 1002881560322940000, 'eCounter', 2 );
INSERT INTO elementdetail VALUES ( 1002881560322940000, 'other_variables', NULL );
INSERT INTO elementdetail VALUES ( 1002271560322950000, 'eCounter', 0 );
INSERT INTO elementdetail VALUES ( 1002271560322950000, 'other_variables', NULL );
INSERT INTO elementdetail VALUES ( 1002951560322970000, 'eCounter', 1 );
INSERT INTO elementdetail VALUES ( 1002951560322970000, 'other_variables', NULL );
INSERT INTO elementdetail VALUES ( 1002231560322980000, 'eCounter', 2 );
INSERT INTO elementdetail VALUES ( 1002231560322980000, 'other_variables', NULL );
INSERT INTO elementdetail VALUES ( 1002781560323000000, 'eCounter', 0 );
INSERT INTO elementdetail VALUES ( 1002781560323000000, 'other_variables', NULL );
INSERT INTO elementdetail VALUES ( 1002891560323020000, 'eCounter', 1 );
INSERT INTO elementdetail VALUES ( 1002891560323020000, 'other_variables', NULL );
INSERT INTO elementdetail VALUES ( 1002391560323040000, 'eCounter', 2 );
INSERT INTO elementdetail VALUES ( 1002391560323040000, 'other_variables', NULL );
We can do something like this, making use of a CTE:
WITH cte_element AS
(
SELECT
e.callid,
e.elementname,
d.varvalue
FROM
element AS e
INNER JOIN
elementdetail AS d
ON
e.elementid = d.elementid
WHERE
d.varname = 'eCounter'
ORDER BY
e.callid,
d.varvalue
)
SELECT
vt1.elementname,
COUNT( vt1.elementname ) AS count_elementname
FROM
(
SELECT
tmp1.callid,
tmp1.elementname,
tmp1.varvalue
FROM
cte_element AS tmp1
WHERE
tmp1.varvalue =
(
SELECT
MAX( tmp2.varvalue )
FROM
cte_element AS tmp2
WHERE
tmp1.callid = tmp2.callid
GROUP BY
tmp2.callid
)
) AS vt1
GROUP BY
vt1.elementname
;
-- Results
elementname count_elementname
set_Page6 2
set_Page4 2
Still using a a recent version of Informix, using windowing instead of a CTE:
SELECT
vt1.elementname,
COUNT( vt1.elementname ) AS count_elementname
FROM
(
SELECT
e.callid,
e.elementname,
d.varvalue,
RANK() OVER
(
PARTITION BY e.callid ORDER BY e.callid, d.varvalue DESC
) AS rank
FROM
element AS e
INNER JOIN
elementdetail AS d
ON
e.elementid = d.elementid
WHERE
d.varname = 'eCounter'
ORDER BY
e.callid,
d.varvalue
) AS vt1
WHERE
vt1.rank = 1
GROUP BY
vt1.elementname
;
-- Results
elementname count_elementname
set_Page6 2
set_Page4 2
With an older Informix version, without CTE's or windowing, so we use a temporary table:
SELECT
e.callid,
e.elementname,
d.varvalue
FROM
element AS e
INNER JOIN
elementdetail AS d
ON
e.elementid = d.elementid
WHERE
d.varname = 'eCounter'
ORDER BY
e.callid,
d.varvalue
INTO TEMP temp_element
;
SELECT
vt1.elementname,
COUNT( vt1.elementname ) AS count_elementname
FROM
(
SELECT
tmp1.callid,
tmp1.elementname,
tmp1.varvalue
FROM
temp_element AS tmp1
WHERE
tmp1.varvalue =
(
SELECT
MAX( tmp2.varvalue )
FROM
temp_element AS tmp2
WHERE
tmp1.callid = tmp2.callid
GROUP BY
tmp2.callid
)
) AS vt1
GROUP BY
vt1.elementname
;
-- Results
elementname count_elementname
set_Page6 2
set_Page4 2
I have no idea of how any of this queries will scale when you use a more robust data set ( hundred thousands or millions of rows on each table ).
I have not tested any corner case, for example, when a callid has 2 elementname with the same eCounter varvalue values.

Related

How to ensure both values in a column existis in the table for a particular conditiion?

I have the following structure of tables and columns
Table1: bin_master
Column1: bin_code values: (B1,B2 etc)
Column2: bin_type values: (P, R)
Column3: area values: (A1, A2)
Table2: area_master
Column1: area values: (A1,A2)
create table dum_table1_bin_master
(
bin_code varchar2(25),
bin_type varchar2(1),
area varchar2(25)
);
create table dum_table2_area_master
(
area varchar2(25),
area_desc varchar2(25)
);
insert into dum_table1_bin_master values ('B1','P','A1');
insert into dum_table1_bin_master values ('B1','R','A1');
insert into dum_table1_bin_master values ('B2','P','A1');
insert into dum_table1_bin_master values ('B2','P','A1');
insert into dum_table1_bin_master values ('B2','R','A2');
insert into dum_table1_bin_master values ('B2','R','A2');
insert into dum_table1_bin_master values ('B3','A','A2');
insert into dum_table1_bin_master values ('B3','A','A2');
insert into dum_table2_area_master values ('A1', 'AREA 1 DESCRIPTION');
insert into dum_table2_area_master values ('A2', 'AREA 2 DESCRIPTION');
Expected Output should be:
B1 P A1
B1 R A1
Since the Bin code B1 has both P and R bin_type.
In short, how do I write a query to fetch the bin code which have both P and R bin_type for a particular area ?
Thanks

How to use an AND statement with ARRAYFORMULA when searching a range in a Google Sheet

I have this function which works great.
=transpose
(
split
(
ARRAYFORMULA
(
TEXTJOIN
(
", ",TRUE,
(
IF
(
A3:A100="Active",
B3:B100
,""
)
)
)
),","
)
)
It says if Anything Between A3 and A100 is the word Active, then Display B3 in a vertical list.
I am trying to query multiple parameters though and am hitting dead ends. When I try to add an AND statement to the IF query, I get no results. Example:
=transpose
(
split
(
ARRAYFORMULA
(
TEXTJOIN
(
", ",TRUE,
(
IF
(
AND(A3:A100="Active", C3:C100="Sold"),
B3:B100
,""
)
)
)
),","
)
)
not supported. use multiplication:
=TRANSPOSE(SPLIT(ARRAYFORMULA(TEXTJOIN(", ", 1,
IF((A3:A100="Active")*(C3:C100="Sold"), B3:B100, ))), ","))

Count current and longest streak from null or 1 values

I'm trying to count longest and current streak from null or 1 values in google sheets.
It's going to be used in Data Studio, but I have to make calculation in Sheets.
I've tried a sultion from below post, but it's nor working for me and also I have null values not 0, and it has to stay this way (rows in sheet are being appended from google forms form, where I check whether I did a habit or not).
Google Sheets - How to count streaks of non-zero numbers on one column
Please help if you can, thanks before
Here is the spreadsheet with some example data
https://docs.google.com/spreadsheets/d/1GaaEJ24ERulPftYAILOuokY929HInkh-SjAJUEvrW5M/edit?usp=sharing
values to visualize in streaks
Use this to get the longest streak in data:
=arrayformula(
if(
len(join(""; Data!A1:A));
max( len( split(
concatenate( left(isblank(Data!A1:A)) );
"T"
) ) );
"no streak"
)
)
And this to get the last streak in the data:
=+sort(
if(
len(join(""; Data!A1:A));
len( transpose( split(
concatenate( left(isblank(Data!A1:A)) );
"T"
) ) );
"no streak"
);
sequence( rows(
transpose( split(
concatenate( left(isblank(Data!A1:A)) );
"T"
) )
) );
false
)
See your sample spreadsheet.
longest:
=INDEX(COLUMNS(SPLIT(FLATTEN(SPLIT(TRIM(QUERY(IF(A1:A=""; 0; "×");;9^9)); " 0 "; )); " ")))
all:
=INDEX(QUERY(LEN(SUBSTITUTE(FLATTEN(TRIM(SPLIT(QUERY(
IF(A1:A=""; "×"; "¤");;9^9); "×"; ))); " "; ));
"where Col1 <> 0"))
last:
=INDEX(QUERY(SORT(LEN(SUBSTITUTE(FLATTEN(TRIM(SPLIT(QUERY(
IF(A1:A=""; "×"; "¤");;9^9); "×"; ))); " "; ));
SEQUENCE(ROWS(A1:A)-COUNTA(A1:A)); 0); "where Col1 <> 0 limit 1"; ))

Store the result of sql and process it in informix

We have a view which contains 2 columns: pattern_start_time, pattern_end_time.
The select query in the function will convert it to minutes and using that result we are processing to get the shift unused coverage.The function is getting created but the processing is not happening and getting the below error:
SQLError[IX000]:Routine (my_list) cant be resolved.
Also please enter image description heresuggest to loop till the length of the result.
CREATE function myshifttesting(orgid int) returning int;
DEFINE my_list LIST( INTEGER not null );
DEFINE my_list1 LIST( INTEGER not null );
define i, j, sub, sub1 int;
define total int;
TRACE ON;
TRACE 'my testing starts';
INSERT INTO TABLE( my_list )
select
((extend(current, year to second) + (dots.v_shift_coverage.pattern_start_time - datetime(00:00) hour to minute) - current)::interval minute(9) to minute)::char(10)::INTEGER
from
dots.v_shift_coverage
where
org_guid = orgid;
INSERT INTO TABLE( my_list1 )
select
((extend(current, year to second) + (dots.v_shift_coverage.pattern_end_time - datetime(00:00) hour to minute) - current)::interval minute(9) to minute)::char(10)::INTEGER
from
dots.v_shift_coverage
where
org_guid = orgid;
let sub = 0;
let sub1 = 0;
let total = 0;
for j = 0 to 4
if (my_list(j) < my_list1(j))
then
if (my_list(j + 1) > my_list1(j))
then
let sub = sub + my_list(j + 1) - my_list1(j);
end if;
end if;
end for
if (my_list(0) > my_list1(4))
then
let sub1 = my_list(0) - my_list1(4);
end if;
let total = sub + sub1;
return total;
end function;
The error that you are receiving is because my_list(j) is not valid Informix syntax to access a LIST element. Informix is interpreting my_list(j) as a call to a function named mylist.
You can use a temporary table to "emulate" an array with your logic, something like this:
CREATE TABLE somedata
(
letter1 CHAR( 2 ),
letter2 CHAR( 2 )
);
INSERT INTO somedata VALUES ( 'a1', 'a2' );
INSERT INTO somedata VALUES ( 'b1', 'b2' );
INSERT INTO somedata VALUES ( 'c1', 'c2' );
INSERT INTO somedata VALUES ( 'd1', 'd2' );
INSERT INTO somedata VALUES ( 'e1', 'e2' );
DROP FUNCTION IF EXISTS forloop;
CREATE FUNCTION forloop()
RETURNING CHAR( 2 ) AS letter1, CHAR( 2 ) AS letter2;
DEFINE number_of_rows INTEGER;
DEFINE iterator INTEGER;
DEFINE my_letter1 CHAR( 2 );
DEFINE my_letter2 CHAR( 2 );
-- Drop temp table if it already exists in the session
DROP TABLE IF EXISTS tmp_data;
CREATE TEMP TABLE tmp_data
(
tmp_id SERIAL,
tmp_letter1 CHAR( 2 ),
tmp_letter2 CHAR( 2 )
);
-- Insert rows into the temp table, serial column will be the access key
INSERT INTO tmp_data
SELECT 0,
d.letter1,
d.letter2
FROM somedata AS d
ORDER BY d.letter1;
-- Get total rows of temp table
SELECT COUNT( * )
INTO number_of_rows
FROM tmp_data;
FOR iterator = 1 TO number_of_rows
SELECT d.tmp_letter1
INTO my_letter1
FROM tmp_data AS d
WHERE d.tmp_id = iterator;
-- Check if not going "out of range"
IF iterator < number_of_rows THEN
SELECT d.tmp_letter2
INTO my_letter2
FROM tmp_data AS d
WHERE d.tmp_id = iterator + 1;
ELSE
-- iterator + 1 is "out of range", return to the beginning
SELECT d.tmp_letter2
INTO my_letter2
FROM tmp_data AS d
WHERE d.tmp_id = 1;
END IF;
RETURN my_letter1, my_letter2 WITH RESUME;
END FOR;
END FUNCTION;
-- Running the function
EXECUTE FUNCTION forloop();
-- Results
letter1 letter2
a1 b2
b1 c2
c1 d2
d1 e2
e1 a2
5 row(s) retrieved.

Failed to make query with an explicit join sequence (including alias table) on SQLAlchemy

I have trouble on making a SQLAlchemy query between two tables:
ProcessedDataset
- ID
ProcDSParent
- ThisDataset (foreign key to ProcessedDataset.ID)
- ItsParent (foreign key to ProcessedDataset.ID)
To find the Parent and Child of a Dataset, I need explicit
specify the join sequence between:
ProcessedDataset <-- ProcDSParent --> ProcessedDataset
After make different alias for them, I try different join approach,
but still not able to get it.
Demonstrate with find Parent of a Dataset:
dataset = DB.db_tables[db_alias]['ProcessedDataset']
dsparent = DB.db_tables[db_alias]['ProcDSParent']
parent = dataset.alias('ProcessedDataset_ItsParent')
child_parent = dsparent.alias('ThisDataset_ItsParent')
keylist = [parent.c.Name]
whereclause = dataset.c.Name.op('=')('Test')
Approach <1>:
FromClause.join + expression.select
r_join = dataset
r_join.join(child_parent, dataset.c.ID == child_parent.c.ThisDataset)
r_join.join(parent, child_parent.c.ItsParent == parent.c.ID)
query = select(keylist, from_obj=r_join, whereclause=whereclause)
print query
SELECT `ProcessedDataset_ItsParent`.`Name`
FROM `ProcessedDataset` AS `ProcessedDataset_ItsParent`, `ProcessedDataset`
WHERE `ProcessedDataset`.`Name` = %s
Approach <2>:
orm.join + expression.select
join2 = join(dataset, child_parent, dataset.c.ID == child_parent.c.ThisDataset)
join2.join(dsparent, child_parent.c.ItsParent == parent.c.ID)
print query
SELECT `ProcessedDataset_ItsParent`.`Name`
FROM `ProcessedDataset` AS `ProcessedDataset_ItsParent`,
`ProcessedDataset` INNER JOIN `ProcDSParent` AS `ThisDataset_ItsParent` ON
`ProcessedDataset`.`ID` = `ThisDataset_ItsParent`.`ThisDataset`
WHERE `ProcessedDataset`.`Name` = %s
As you can see, none of them are Parent of a Dataset, which should be:
SELECT `ProcessedDataset_ItsParent`.`Name`
FROM `ProcessedDataset`
INNER JOIN `ProcDSParent` AS `ThisDataset_ItsParent` ON
`ProcessedDataset`.`ID` = `ThisDataset_ItsParent`.`ThisDataset`
INNER JOIN `ProcessedDataset` AS `ProcessedDataset_ItsParent` ON
`ThisDataset_ItsParent`.'ItsParent` = `ProcessedDataset_ItsParent`.`ID`
WHERE `ProcessedDataset`.`Name` = %s
Appreciate for any help, stuck here for couple of days already!
Dong
Attaching minimal DDL and python code
CREATE TABLE ProcessedDataset
(
ID BIGINT UNSIGNED not null auto_increment,
Name varchar(500) not null,
primary key(ID)
) ;
CREATE TABLE ProcDSParent
(
ID BIGINT UNSIGNED not null auto_increment,
ThisDataset BIGINT UNSIGNED not null,
ItsParent BIGINT UNSIGNED not null,
primary key(ID),
unique(ThisDataset,ItsParent)
) ;
ALTER TABLE ProcDSParent ADD CONSTRAINT
ProcDSParent_ThisDataset_FK foreign key(ThisDataset) references ProcessedDataset(ID) on delete CASCADE
;
ALTER TABLE ProcDSParent ADD CONSTRAINT
ProcDSParent_ItsParent_FK foreign key(ItsParent) references ProcessedDataset(ID) on delete CASCADE
;
INSERT INTO ProcessedDataset VALUES (0, "ds0");
INSERT INTO ProcessedDataset VALUES (1, "ds1");
INSERT INTO ProcessedDataset VALUES (2, "ds2");
INSERT INTO ProcessedDataset VALUES (3, "ds3");
INSERT INTO ProcessedDataset VALUES (4, "ds4");
INSERT INTO ProcessedDataset VALUES (5, "ds5");
INSERT INTO ProcessedDataset VALUES (6, "ds6");
INSERT INTO ProcessedDataset VALUES (7, "ds7");
INSERT INTO ProcDSParent VALUES (0, 0, 1);
INSERT INTO ProcDSParent VALUES (1, 2, 1);
INSERT INTO ProcDSParent VALUES (2, 1, 3);
INSERT INTO ProcDSParent VALUES (3, 3, 4);
INSERT INTO ProcDSParent VALUES (4, 5, 6);
INSERT INTO ProcDSParent VALUES (5, 7, 6);
(ds0, ds2)-> ds1 -> ds3 -> ds4
(ds5, ds7) -> ds6
from sqlalchemy import Table, create_engine, MetaData
from sqlalchemy import and_
from sqlalchemy.sql import select
from sqlalchemy.orm import join
url = 'mysql://cms:passcms#localhost:3306/testbed'
engine = create_engine(url, strategy = 'threadlocal')
kwargs = {'autoload':True}
db_meta = MetaData()
db_meta.bind = engine
dataset = Table('ProcessedDataset', db_meta, **kwargs)
dsparent = Table('ProcDSParent', db_meta, **kwargs)
parent = dataset.alias('ProcessedDataset_ItsParent')
child_parent = dsparent.alias('ThisDataset_ItsParent')
keylist = [parent.c.Name]
whereclause = dataset.c.Name.op('=')('ds0')
r_join = dataset
r_join.join(child_parent, dataset.c.ID == child_parent.c.ThisDataset)
r_join.join(parent, child_parent.c.ItsParent == parent.c.ID)
query = select(keylist, whereclause)
print query
print engine.execute(query).fetchall()
query.append_from(r_join)
print query
print engine.execute(query).fetchall()
query = select(keylist, from_obj=r_join, whereclause=whereclause)
print query
print engine.execute(query).fetchall()
join2 = join(dataset, child_parent, dataset.c.ID == child_parent.c.ThisDataset)
join2.join(dsparent, child_parent.c.ItsParent == parent.c.ID)
query.append_from(join2)
print query
print engine.execute(query).fetchall()
query = select(keylist, from_obj=join2, whereclause=whereclause)
print query
print engine.execute(query).fetchall()
Michael Bayer Replied my via mail.
the join() method returns a new Join object, that's the one which represents the join. The original object is unchanged:
r_join = dataset
r_join = r_join.join(child_parent, ...)
r_join = r_join.join(parent, ...)
AND also I tried out the orm.join:
join1 = join(child_parent, dataset, child_parent.c.ThisDataset == dataset.c.ID)
join2 = parent.join(join1, parent.c.ID == child_parent.c.ItsParent)

Resources