Having trouble with Postgres unnest array syntax - arrays

I am looking for guidance on the best way to do this insert. I am trying to create 11 entries for role_id 58385 while looping through the values of each of these arrays. I am new to PostgreSQL and need some guidance as to what I am doing wrong in this instance.
INSERT INTO public.acls (role_id, acl_id, update, can_grant, retrieve, create, archive) VALUES (
'58385',
unnest(array[1,14,20,21,22,24,25,26,36,300,302]),
unnest(array[f,f,t,t,f,f,f,t,f,t,t]),
unnest(array[f,f,f,f,f,f,f,f,f,f,f]),
unnest(array[t,t,t,t,t,t,t,t,t,t,t]),
unnest(array[f,f,t,t,f,f,f,t,f,t,t]),
unnest(array[f,f,f,f,f,f,f,f,f,f,f])
)
Do I need a SELECT subquery for each of the arrays? Or could I make one array from the six and Insert them.

A single select will do it for you, but t and f will need to be true and false:
select '58385',
unnest(array[1,14,20,21,22,24,25,26,36,300,302]),
unnest(array[false,false,true,true,false,false,false,true,false,true,true]),
unnest(array[false,false,false,false,false,false,false,false,false,false,false]),
unnest(array[true,true,true,true,true,true,true,true,true,true,true]),
unnest(array[false,false,true,true,false,false,false,true,false,true,true]),
unnest(array[false,false,false,false,false,false,false,false,false,false,false])
;
?column? | unnest | unnest | unnest | unnest | unnest | unnest
----------+--------+--------+--------+--------+--------+--------
58385 | 1 | f | f | t | f | f
58385 | 14 | f | f | t | f | f
58385 | 20 | t | f | t | t | f
58385 | 21 | t | f | t | t | f
58385 | 22 | f | f | t | f | f
58385 | 24 | f | f | t | f | f
58385 | 25 | f | f | t | f | f
58385 | 26 | t | f | t | t | f
58385 | 36 | f | f | t | f | f
58385 | 300 | t | f | t | t | f
58385 | 302 | t | f | t | t | f
(11 rows)

Related

How to return first not empty cell from importrange values?

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:

Multiple outcomes/scenarios

I got a problem that I have already created a solution for, but I'm wondering if there's a better way of solving the problem. Basically I have to create a flag for certain scenarios under a partition of ID and date. My solution involved mapping for all the possible scenarios, then creating "case when" statements for all these scenarios with the specific outcome. Basically, I was the one that created the outcomes. I am wondering if there's another way, something around letting SQL create the outcomes instead of myself.
Thanks a lot!
Background:
+----+-----------+--------+-------+------+-----------------+-----------------------------------------------------------------------------------+
| ID | Month | Status | Value | Flag | Scenario Number | Scenario Description |
+----+-----------+--------+-------+------+-----------------+-----------------------------------------------------------------------------------+
| 1 | 1/01/2016 | First | 123 | No | 1 | First, second and blank exists. Do not flag |
| 1 | 1/01/2016 | Second | 456 | No | 1 | First, second and blank exists. Do not flag |
| 1 | 1/01/2016 | | 789 | No | 1 | First, second and blank exists. Do not flag |
| 1 | 1/02/2016 | Second | 123 | Yes | 2 | First does not exist, two second but have different values. Flag these as Yes |
| 1 | 1/02/2016 | Second | 456 | Yes | 2 | First does not exist, two second but have different values. Flag these as Yes |
| 1 | 1/02/2016 | Second | 123 | No | 3 | First does not exist, two second have same values. Do not flag |
| 1 | 1/02/2016 | Second | 123 | No | 3 | First does not exist, two second have same values. Do not flag |
| 1 | 1/03/2016 | Second | 123 | No | 4 | Only one entry of Second exist. Do no flag |
| 1 | 1/04/2016 | | 123 | Yes | 5 | Two blanks for the partition. Flag these as Yes |
| 1 | 1/04/2016 | | 123 | Yes | 5 | Two blanks for the partition. Flag these as Yes |
| 1 | 1/05/2016 | | | No | 6 | Only one entry of blank exist. Do not flag these |
| 1 | 1/06/2016 | First | 123 | Yes | 7 | First exist for the partition. Do not flag |
| 1 | 1/06/2016 | | 456 | Yes | 7 | First exist for the partition. Do not flag |
| 1 | 1/07/2016 | Second | 123 | Yes | 8 | First does not exist and second and blank do not have the same value. Flag these. |
| 1 | 1/07/2016 | | 456 | Yes | 8 | First does not exist and second and blank do not have the same value. Flag these. |
| 1 | 1/07/2016 | Second | 123 | Yes | 8 | First does not exist and second and blank have the same value. Flag these. |
| 1 | 1/07/2016 | | 123 | Yes | 8 | First does not exist and second and blank have the same value. Flag these. |
+----+-----------+--------+-------+------+-----------------+-----------------------------------------------------------------------------------+
Data:
+----+-----------+-------+----------+---------------+
| ID | Month | Value | Priority | Expected_Flag |
+----+-----------+-------+----------+---------------+
| 1 | 1/01/2016 | 96.01 | | Yes |
| 1 | 1/01/2016 | 96.01 | | Yes |
| 1 | 1/02/2016 | 65.2 | First | No |
| 1 | 1/02/2016 | 3.47 | Second | No |
| 1 | 1/02/2016 | 45.99 | | No |
| 11 | 1/01/2016 | 25 | | No |
| 11 | 1/02/2016 | 74.25 | Second | No |
| 11 | 1/02/2016 | 74.25 | Second | No |
| 11 | 1/02/2016 | 23.25 | | No |
| 24 | 1/01/2016 | 1.25 | First | No |
| 24 | 1/01/2016 | 1.365 | | No |
| 24 | 1/04/2016 | 1.365 | First | No |
| 24 | 1/04/2016 | 1.365 | | No |
| 24 | 1/05/2016 | 1.365 | First | No |
| 24 | 1/05/2016 | 1.365 | First | No |
| 24 | 1/06/2016 | 1.365 | Second | No |
| 24 | 1/06/2016 | 1.365 | Second | No |
| 24 | 1/07/2016 | 1.365 | Second | Yes |
| 24 | 1/07/2016 | 1.365 | | Yes |
| 24 | 1/08/2016 | 1.365 | First | No |
| 24 | 1/08/2016 | 1.365 | | No |
| 24 | 1/09/2016 | 1.365 | Second | No |
| 24 | 1/09/2016 | 1.365 | | No |
| 27 | 1/01/2016 | 0 | Second | Yes |
| 27 | 1/01/2016 | 0 | Second | Yes |
| 27 | 1/02/2016 | 45.25 | Second | No |
| 3 | 1/01/2016 | 96.01 | First | No |
| 3 | 1/01/2016 | 96.01 | First | No |
| 3 | 1/03/2016 | 96.01 | First | No |
| 3 | 1/03/2016 | 96.01 | First | No |
| 35 | 1/01/2016 | | | Yes |
| 35 | 1/01/2016 | | | Yes |
| 35 | 1/02/2016 | | First | No |
| 35 | 1/02/2016 | | Second | No |
| 35 | 1/02/2016 | | | No |
| 35 | 1/02/2016 | | | No |
| 35 | 1/03/2016 | | Second | Yes |
| 35 | 1/03/2016 | | Second | Yes |
| 35 | 1/04/2016 | | Second | No |
| 35 | 1/04/2016 | | Second | No |
+----+-----------+-------+----------+---------------+

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) |
+----------------+------+---------+-----------------+------------------------------------------------------------------------------------------------------------+

How to make a SQL "IF-THEN-ELSE" statement

I've seen other questions about SQL If-then-else stuff, but I'm not seeing how to relate it to what I'm trying to do. I've been using SQL for about a year now but only basic stuff and never this.
If I have a SQL table that looks like this
| Name | Version | Category | Value | Number |
|:-----:|:-------:|:--------:|:-----:|:------:|
| File1 | 1.0 | Time | 123 | 1 |
| File1 | 1.0 | Size | 456 | 1 |
| File1 | 1.0 | Final | 789 | 1 |
| File2 | 1.0 | Time | 312 | 1 |
| File2 | 1.0 | Size | 645 | 1 |
| File2 | 1.0 | Final | 978 | 1 |
| File3 | 1.0 | Time | 741 | 1 |
| File3 | 1.0 | Size | 852 | 1 |
| File3 | 1.0 | Final | 963 | 1 |
| File1 | 1.1 | Time | 369 | 2 |
| File1 | 1.1 | Size | 258 | 2 |
| File1 | 1.1 | Final | 147 | 2 |
| File2 | 1.1 | Time | 741 | 2 |
| File2 | 1.1 | Size | 734 | 2 |
| File2 | 1.1 | Final | 942 | 2 |
| File3 | 1.1 | Time | 997 | 2 |
| File3 | 1.1 | Size | 997 | 2 |
| File3 | 1.1 | Final | 985 | 2 |
How can I write a SQL IF, ELSE statement that creates a new column called "Replication" that follows this rule:
A = B + 1 when x = 1
else
A = B
where A = the number we will use for the next Number
B = Max(Number)
x = Replication count (this is the number of times that a loop is executed. x=i)
The results table will look like this:
| Name | Version | Category | Value | Number | Replication |
|:-----:|:-------:|:--------:|:-----:|:------:|:-----------:|
| File1 | 1.0 | Time | 123 | 1 | 1 |
| File1 | 1.0 | Size | 456 | 1 | 1 |
| File1 | 1.0 | Final | 789 | 1 | 1 |
| File2 | 1.0 | Time | 312 | 1 | 1 |
| File2 | 1.0 | Size | 645 | 1 | 1 |
| File2 | 1.0 | Final | 978 | 1 | 1 |
| File1 | 1.0 | Time | 369 | 1 | 2 |
| File1 | 1.0 | Size | 258 | 1 | 2 |
| File1 | 1.0 | Final | 147 | 1 | 2 |
| File2 | 1.0 | Time | 741 | 1 | 2 |
| File2 | 1.0 | Size | 734 | 1 | 2 |
| File2 | 1.0 | Final | 942 | 1 | 2 |
| File1 | 1.1 | Time | 997 | 2 | 1 |
| File1 | 1.1 | Size | 997 | 2 | 1 |
| File1 | 1.1 | Final | 985 | 2 | 1 |
| File2 | 1.1 | Time | 438 | 2 | 1 |
| File2 | 1.1 | Size | 735 | 2 | 1 |
| File2 | 1.1 | Final | 768 | 2 | 1 |
| File1 | 1.1 | Time | 786 | 2 | 2 |
| File1 | 1.1 | Size | 486 | 2 | 2 |
| File1 | 1.1 | Final | 135 | 2 | 2 |
| File2 | 1.1 | Time | 379 | 2 | 2 |
| File2 | 1.1 | Size | 943 | 2 | 2 |
| File2 | 1.1 | Final | 735 | 2 | 2 |
EDIT: Based on the answer by Sean Lange, this is my 2nd attempt at a solution:
SELECT COALESCE(MAX)(Number) + CASE WHEN Replication = 1 then 1 else 0, 1) FROM Table
The COALESCE is in there for when there is no value yet in the Number column.
The IF/Else construct is used to control flow of statements in t-sql. You want a case expression, which is used to conditionally return values in a column.
https://msdn.microsoft.com/en-us/library/ms181765.aspx
Yours would be something like:
case when x = 1 then A else B end as A
As SeanLange pointed out in this case it would be better to use an CASE/WHEN but to illustrate how to use If\ELSE the way to do it in sql is like this:
if x = 1
BEGIN
---Do something
END
ELSE
BEGIN
--Do something else
END
I would say the best way to know the difference and when to use which is if you are writing a query and want a different field to appear based on a certain condition, use case/when. If a certain condition will cause a series of steps to happen then use if/else

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