How to return first not empty cell from importrange values? - arrays

my google sheet excel document contain data like this
+---+---+---+---+---+---+
| | A | B | C | D | E |
+---+---+---+---+---+---+
| 1 | | c | | x | |
+---+---+---+---+---+---+
| 2 | | r | | 4 | |
+---+---+---+---+---+---+
| 3 | | | | m | |
+---+---+---+---+---+---+
| 4 | | | | | |
+---+---+---+---+---+---+
Column B and D contain data provided by IMPORTRANGE function, which are store in different files.
And i would like to fill column A with first not empty value in row, in other words: desired result must look like this:
+---+---+---+---+---+---+
| | A | B | C | D | E |
+---+---+---+---+---+---+
| 1 | c | c | | x | |
+---+---+---+---+---+---+
| 2 | r | r | | 4 | |
+---+---+---+---+---+---+
| 3 | m | | | m | |
+---+---+---+---+---+---+
| 4 | | | | | |
+---+---+---+---+---+---+
I tried ISBLANK function, but apperantly if column is imported then, even if the value is empty, is not blank, so this function dosn't work for my case. Then i tried QUERY function in 2 different variant:
1) =QUERY({B1;D1}; "select Col1 where Col1 is not null limit 1"; 0) but result in this case is wrong when row contain cells with numbers. Result with this query is following:
+---+---+---+---+---+---+
| | A | B | C | D | E |
+---+---+---+---+---+---+
| 1 | c | c | | x | |
+---+---+---+---+---+---+
| 2 | 4 | r | | 4 | |
+---+---+---+---+---+---+
| 3 | m | | | m | |
+---+---+---+---+---+---+
| 4 | | | | | |
+---+---+---+---+---+---+
2) =QUERY({B1;D1};"select Col1 where Col1 <> '' limit 1"; 0) / =QUERY({B1;D1};"select Col1 where Col1 != '' limit 1"; 0) and this dosn't work at all, result is always #N/A
Also i would like to avoid using nested IFs and javascript scripts, if possible, as solution with QUERY function suits for my case best due to easy expansion to another columns without any deeper knowladge about programming. Is there any way how to make it simply, just with QUERY, and i am just missing something, or i have to use IFs/javascript?

try:
=ARRAYFORMULA(SUBSTITUTE(INDEX(IFERROR(SPLIT(TRIM(TRANSPOSE(QUERY(
TRANSPOSE(SUBSTITUTE(B:G, " ", "♦")),,99^99))), " ")),,1), "♦", " "))
selective columns:

Related

SQLite merge duplicates

I have a SQLite table, in which there are some Rows which differ in just one column.
I want to merge the entrys in this Column with a seperator (line break in my case).
So, this:
| id | block | description|
------------------------------
| 1 | a | foo |
| 1 | a | bar |
| 3 | b | cat |
| 4 | c | mouse |
------------------------------
Should become this:
| id | block | description|
------------------------------
| 1 | a | foo \r\n bar|
| 3 | b | cat |
| 4 | c | mouse |
------------------------------
I don't even have an Idea what to search for (instead of "merge", but I couldn't find anything suitable for my application), so any Input would be appreciated.
Jann
I think you are looking for group_concat():
select id, block, group_concat(description, ' \r\n ')
from t
group by id, block;

Performance of CYPHER 2.3 in Neo4j query

I am having a problem in a Neo4j query. Suppose I have a Node type called App. The App nodes have the fields "m_id" and "info". I want to build a query to create a relationship between the nodes where the field "info" is equal.
This is the query:
MATCH (a:App {m_id:'SOME_VALUE' }),(b:App {info: a.info}) WHERE ID(a)<>ID(b) AND NOT (b)-[:INFO]->(a) MERGE (a)-[r:INFO]->(b) RETURN b.m_id;
I also have indexes for both fields:
CREATE CONSTRAINT ON (a:App) ASSERT a.m_id IS UNIQUE;
CREATE INDEX ON :App(info);
But the thing is I get very slow queries, with access in all the records of the App nodes.
This is the profile of the query:
+---------------+--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+
| Operator | Rows | DB Hits | Identifiers | Other |
+---------------+--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+
| +ColumnFilter | 0 | 0 | b.m_id | keep columns b.m_id |
| | +--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+
| +Extract | 0 | 0 | a, b, b.m_id, r | b.m_id |
| | +--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+
| +Merge(Into) | 0 | 1 | a, b, r | (a)-[r:INFO]->(b) |
| | +--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+
| +Eager | 0 | 0 | a, b | |
| | +--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+
| +Filter | 0 | 2000000 | a, b | Ands(b.info == a.info, NOT(IdFunction(a) == IdFunction(b)), NOT(nonEmpty(PathExpression((b)-[anon[104]:INFO]->(a), true)))) |
| | +--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+
| +SchemaIndex | 184492 | 1000000 | a, b | { AUTOSTRING0}; :App(m_id) |
| | +--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+
| +NodeByLabel | 184492 | 1000001 | b | :App |
+---------------+--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+
Try finding a by itself, using a WITH clause to put a.info into a temporary variable that is used by a separate MATCH clause for b, as in:
MATCH (a:App { m_id:'SOME_VALUE' })
WITH a, a.info AS a_info
MATCH (b:App { info: a_info })
WHERE a <> b AND NOT (b)-[:INFO]->(a)
MERGE (a)-[r:INFO]->(b)
RETURN b.m_id;
It seems that indices tend not to be used when comparing the properties of 2 nodes. The use of a_info removes that impediment.
If the profile of the above shows that one or both indices are not being used, you can try adding index hints:
MATCH (a:App { m_id:'SOME_VALUE' })
USING INDEX a:App(m_id)
WITH a, a.info AS a_info
MATCH (b:App { info: a_info })
USING INDEX b:App(info)
WHERE a <> b AND NOT (b)-[:INFO]->(a)
MERGE (a)-[r:INFO]->(b)
RETURN b.m_id;
I figure out a solution using OPTIONAL MATCH:
MATCH (a:App {m_id:'SOME_VALUE' }) OPTIONAL MATCH (a),(b:App {info: a.info}) WHERE ID(a)<>ID(b) AND NOT (b)-[:INFO]->(a) MERGE (a)-[r:INFO]->(b) RETURN b.m_id;
This is the profile of the query:
+----------------+------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
| Operator | Rows | DB Hits | Identifiers | Other |
+----------------+------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
| +ColumnFilter | 0 | 0 | b.m_id | keep columns b.m_id |
| | +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
| +Extract | 0 | 0 | a, b, b.m_id, r | b.m_id |
| | +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
| +Merge(Into) | 0 | 1 | a, b, r | (a)-[r:INFO]->(b) |
| | +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
| +Eager | 0 | 0 | a, b | |
| | +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
| +OptionalMatch | 0 | 0 | a, b | |
| |\ +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
| | +Filter | 0 | 0 | a, b | Ands(NOT(IdFunction(a) == IdFunction(b)), NOT(nonEmpty(PathExpression((b)-[anon[109]:INFO]->(a), true)))) |
| | | +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
| | +SchemaIndex | 0 | 0 | a, b | a.info; :App(info) |
| | | +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
| | +Argument | 0 | 0 | a | |
| | +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
| +SchemaIndex | 0 | 1 | a | { AUTOSTRING0}; :App(m_id) |
+----------------+------+---------+-----------------+------------------------------------------------------------------------------------------------------------+

Stripping out dates, of several formats, from strings

I have a column of strings, called "MyStrings" like the following:
...
Foo bar Jul15 blah blah.xlsx
Choo bar Jul-15 blah far.xlsx
Star bar 10-Jul-15 blah far.xlsx
Car Star bar 10.Jul.2015 blah far.xlsx
...
...
I'd like to do string manipulation so all dates, whatever format, are not included in the results.
So the following query:
SELECT results = <manipulated "MyStrings">
FROM aTable
Should have these results:
...
Foo bar blah blah.xlsx
Choo bar blah far.xlsx
Star bar blah far.xlsx
Car Star bar blah far.xlsx
...
...
Is there a quick way of doing this or do I need to consider each format individually?
You need a Split function
If you split first by <space> is easy create regular expresion for
monDD
mon-DD
DD-mon-YY
DD-mon-YYYY
SQL Fiddle Demo
WITH splitCTE AS (
SELECT s.[id], f.Number, f.Item
FROM dbo.SourceData AS s
CROSS APPLY dbo.SplitStrings(s.[test], ' ') as f
)
SELECT *,
CASE
WHEN item Like 'Jul[0-9][0-9]' THEN 'mmmdd'
WHEN item Like 'Jul-[0-9][0-9]' THEN 'mmm-dd'
WHEN item Like '[0-9][0-9]-Jul-[0-9][0-9]' THEN 'dd-mmm-yy'
WHEN item Like '[0-9][0-9].Jul.[0-9][0-9][0-9][0-9]' THEN 'dd.mmm.yyyy'
ELSE ''
END matchType
FROM splitCTE
OUTPUT
Need a join with list of 3 char months to replace the wired Jul.
Easy expand to also include a version with full month name.
Will match Jul77 as mmmdd but is a start.
You can calculate a IsValidDate column in another step
For some of the format you can use CONVERT to check for a valid date
For other like Jul77 you can separate first 3 char with last 2 and try to get a date.
.
| id | Number | Item | matchType |
|----|--------|-------------|-------------|
| 1 | 1 | Foo | |
| 1 | 2 | bar | |
| 1 | 3 | Jul15 | mmmdd |
| 1 | 4 | blah | |
| 1 | 5 | blah.xlsx | |
| 2 | 1 | Choo | |
| 2 | 2 | bar | |
| 2 | 3 | Jul-15 | mmm-dd |
| 2 | 4 | blah | |
| 2 | 5 | far.xlsx | |
| 3 | 1 | Star | |
| 3 | 2 | bar | |
| 3 | 3 | 10-Jul-15 | dd-mmm-yy |
| 3 | 4 | blah | |
| 3 | 5 | far.xlsx | |
| 4 | 1 | Car | |
| 4 | 2 | Star | |
| 4 | 3 | bar | |
| 4 | 4 | 10.Jul.2015 | dd.mmm.yyyy |
| 4 | 5 | blah | |
| 4 | 6 | far.xlsx | |
Then use your favorite XML PATH to join back without the matching elements

Generate variables that move information between rows in hierarchical data with spss syntax

I was wondering if you can help me with the following problem in spss syntax.
My dataset has nested structure.
Data are nested in companies, then each company has 1 or 2 bosses, but in this case I care only about boss 1. At a previous stage in time the boss graded the workers (not all of them). Now, the ID and the grade of the workers is on the row each worker.
I would like to move the information that was obtained during worker's assessment and create new sets of variables for each (worker ID and grade) on the line/row of the boss.
+---------+------+--------+--------------+---------+---------+--------+---------+
| company | boss |workerID|worker's grade|N:workID1|N:grade1 |N:work2 |N:grade2 |
+---------+------+--------+--------------+---------+---------+--------+---------+
| A | 1 | 1 | | 3 | A | 4 | A |
| A | 2 | 2 | | | |
| A | 0 | 3 | A | | |
| A | 0 | 4 | A | | |
| A | 0 | 5 | | | |
| B | 1 | 1 | | 3 | B | 4 | A |
| B | 0 | 2 | | | |
| B | 0 | 3 | B | | |
| B | 0 | 4 | A | | |
| C | 1 | 1 | | 2 | D | -1 | -1 |
| C | 0 | 2 | D | | |
I would like to move the worker's id and the grade that to the row of the boss in the NEW variables, without loosing the existing variables on workerID and worker's grade.
Basically, I will need to feed forward the information into the new variables and to the row of boss EQ 1 separately for each company.
I have no idea how to proceed with this. I assume that I need a loop that creates new variable for each worker ID that has a valid grade and then feeds forward the information from the worker's row to the boss' newly generated variables.
Any suggestions are very wellcome :-)
Take a look at VARSTOCASES (Data > Restructure)

Understanding to convert a multi-dimensional array to a one-dimensional array

There is a really good explanation of multi-dimensional array here on stackoverflow which I have studied and researched but i have few follow up questions for anyone who wants to help out. This is not a HW question, it is out of my text book which I am trying to understand more so please confirm if I am looking at the below example correctly. Thank you in advance.
So if i had a 3 dimensional array such as this:
{{{'1','2'},{'3','4'}},
{{'5','6'},{'7','8'}},
{{'9','10'},{'11','12'}}};
Would the one dimensional outcome (using c compiler) simply be?:
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| | | | | | | | | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
And the corresponding position as?
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| | | | | | | | | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
Again I am using this link as my source.
The only thing I am looking for as a form of answer is, am I looking/doing this correctly? If not, I would appreciate it if you can tell me where I have made any mistakes. Thank you again.
1.
char [3][2][2] :
+-----+-----+ +-----+-----+
|+-----+-----+ |+-----+-----+
|| 1 | 3 | || 4 | 5 |
||1,0+-----+-----+ || +-----+-----+
|+---| a | b | |+---| 0 | 1 |
|| 2|0,0,0|0,0,1| || 6| | |
+|1,1+-----+-----+ => +| +-----+-----+
+---| x | y | +---| 2 | 3 |
|0,1,0|0,1,1| | | |
+-----+-----+ +-----+-----+
so your outcome seems ok, and thus (2.) t3[0] should be a.
2.
if t2 looks like this, t2[0][1] is b:
+-----+-----+-----+-----+ +-----+-----+-----+-----+
| a | b | x | y | | | | | |
|0,0,0|0,0,1|0,1,0|0,1,1| | 0,0 | 0,1 | 0,2 | 0,3 |
+-----+-----+-----+-----+ +-----+-----+-----+-----+
| 1 | 3 | 2 | 7 | => | | | | |
|1,0,0|1,0,1|1,1,0|1,1,1| | 1,0 | 1,1 | 1,2 | 1,3 |
+-----+-----+-----+-----+ +-----+-----+-----+-----+
| q | g | r | 4 | | | | | |
|2,0,0|2,0,1|2,1,0|2,1,1| | 2,0 | 2,1 | 2,2 | 2,3 |
+-----+-----+-----+-----+ +-----+-----+-----+-----+
As long you are converting them the right way(as it seems according to the link) it should work...
For conceptual understanding this is a good starting point.
But you should understand the difference between row vs column major. And technically it could vary between compilers and languages depending upon what they are designed for.
http://en.wikipedia.org/wiki/Row-major_order

Resources