Transpose or Pivot - neo4j collect() - neo4j
how to transpose a n x m collection in the return statement ? OR before return statement based on a particular column?
example:
A | B | C
aa | 2 | 3
bb | 4 | 6
cc | 5 | 8
dd | 55| 9
To
aa | bb | cc | dd
2 | 4 | 5 | 55
3 | 6 | 8 | 9
Example:
with [{Label:'User',Lang:'English'},{Label:'Usuario',Lang:'Español'},{Label:'用户',Lang:'中文_简体'}] as t unwind t as p return
this returns
p.Label | p.Lang
User | English
Usuario | Español
用户 | 中文_简体
should be transposed to
User | Usuario | 用户
English | Español | 中文_简体
Well, MAYBE there is what you want in APOC.
CALL apoc.help(KEYWORD)
If not, you are good to write your own function
https://neo4j-contrib.github.io/neo4j-apoc-procedures/#_user_defined_functions
Would extract help? This might get you part-way there:
neo4j> with [{Label:'User',Lang:'English'},{Label:'Usuario',Lang:'Español'},{Label:'用户',Lang:'中文_简体'}] as t return extract( i in t | i.Label), extract(i in t | i.Lang);
+--------------------------------------------------------------+
| extract( i in t | i.Label) | extract(i in t | i.Lang) |
+--------------------------------------------------------------+
| ["User", "Usuario", "用户"] | ["English", "Español", "中文_简体"] |
+--------------------------------------------------------------+
Related
Cypher query aggregate sum of values
I have a Cypher query that shows the following output: +---------------- | usid | count | +---------------- | "000" | 1 | | "000" | 0 | | "000" | 0 | | "001" | 1 | | "001" | 1 | | "001" | 0 | | "002" | 2 | | "002" | 2 | | "002" | 0 | | "003" | 4 | | "003" | 2 | | "003" | 2 | | "004" | 4 | | "004" | 4 | | "004" | 4 | +---------------- How can I get the below result with the condition SUM(count) <= 9. +---------------- | usid | count | +---------------- | "000" | 1 | | "001" | 2 | | "002" | 4 | | "003" | 8 | +---------------- Note: I have used the below query to get the 1st table data. MATCH (us:USER) WITH us WHERE us.count <= 4 RETURN us.id as usid, us.count as count;
I don't know how you get your original data, so I will just use a WITH clause and assume the data is there: // original data WITH usid, count // aggregate and filter WITH usid, sum(count) as new_count WHERE new_count <= 9 RETURN usid, new_count Based on the updated question, the new query would look like: MATCH (us:USER) WHERE us.count <= 4 WITH us.id as usid, sum(us.count) as count WHERE new_count <= 9 RETURN usid, count ˙˙˙
Compare each cell in two rows, but with an exception
I have a table that keeps track of scores from a test. It compares the row with someone's answers to the row with the correct data: A B C D E +--------------+-----+-----+-----+-------+ 1 | | Q1 | Q2 | Q3 | Score | +--------------+-----+-----+-----+-------+ 2 | Answers | C | B | A | | +--------------+-----+-----+-----+-------+ 3 | George | C | A | B | 1 | 4 | Judith | C | C | A | 2 | 5 | James | A | B | C | 1 | +--------------+-----+-----+-----+-------+ The formula behind the Score column is: =arrayformula(sumproduct(($B$2:$D$2=B3:D3))) The first part of sumproduct is a static reference to the Answers row. The second part is comparing it against the row it's on. However I want to add an exception: if the Answers row contains an asterisk it should consider all answers correct: A B C D E +--------------+-----+-----+-----+-------+ 1 | | Q1 | Q2 | Q3 | Score | +--------------+-----+-----+-----+-------+ 2 | Answers | C | * | A | | +--------------+-----+-----+-----+-------+ 3 | George | C | A | B | 2 | 4 | Judith | C | C | A | 3 | 5 | James | A | B | C | 1 | +--------------+-----+-----+-----+-------+ How would I be able to do this?
Please try: =arrayformula(sumproduct(($B$2:$D$2=B3:D3)+($B$2:$D$2="*")))
=IF(OR($B$2=B3, $B$2="*"), 1, )+ IF(OR($C$2=C3, $C$2="*"), 1, )+ IF(OR($D$2=D3, $D$2="*"), 1, ) this will cover up to 51 questions (columns / range of B:AZ) =IF(LEN($B$2),IF(OR($B$2=B3,$B$2="*"),1,),)+ IF(LEN($C$2),IF(OR($C$2=C3,$C$2="*"),1,),)+ IF(LEN($D$2),IF(OR($D$2=D3,$D$2="*"),1,),)+ IF(LEN($E$2),IF(OR($E$2=E3,$E$2="*"),1,),)+ IF(LEN($F$2),IF(OR($F$2=F3,$F$2="*"),1,),)+ IF(LEN($G$2),IF(OR($G$2=G3,$G$2="*"),1,),)+ IF(LEN($H$2),IF(OR($H$2=H3,$H$2="*"),1,),)+ IF(LEN($I$2),IF(OR($I$2=I3,$I$2="*"),1,),)+ IF(LEN($J$2),IF(OR($J$2=J3,$J$2="*"),1,),)+ IF(LEN($K$2),IF(OR($K$2=K3,$K$2="*"),1,),)+ IF(LEN($L$2),IF(OR($L$2=L3,$L$2="*"),1,),)+ IF(LEN($M$2),IF(OR($M$2=M3,$M$2="*"),1,),)+ IF(LEN($N$2),IF(OR($N$2=N3,$N$2="*"),1,),)+ IF(LEN($O$2),IF(OR($O$2=O3,$O$2="*"),1,),)+ IF(LEN($P$2),IF(OR($P$2=P3,$P$2="*"),1,),)+ IF(LEN($Q$2),IF(OR($Q$2=Q3,$Q$2="*"),1,),)+ IF(LEN($R$2),IF(OR($R$2=R3,$R$2="*"),1,),)+ IF(LEN($S$2),IF(OR($S$2=S3,$S$2="*"),1,),)+ IF(LEN($T$2),IF(OR($T$2=T3,$T$2="*"),1,),)+ IF(LEN($U$2),IF(OR($U$2=U3,$U$2="*"),1,),)+ IF(LEN($V$2),IF(OR($V$2=V3,$V$2="*"),1,),)+ IF(LEN($W$2),IF(OR($W$2=W3,$W$2="*"),1,),)+ IF(LEN($X$2),IF(OR($X$2=X3,$X$2="*"),1,),)+ IF(LEN($Y$2),IF(OR($Y$2=Y3,$Y$2="*"),1,),)+ IF(LEN($Z$2),IF(OR($Z$2=Z3,$Z$2="*"),1,),)+ IF(LEN($AA$2),IF(OR($AA$2=AA3,$AA$2="*"),1,),)+ IF(LEN($AB$2),IF(OR($AB$2=AB3,$AB$2="*"),1,),)+ IF(LEN($AC$2),IF(OR($AC$2=AC3,$AC$2="*"),1,),)+ IF(LEN($AD$2),IF(OR($AD$2=AD3,$AD$2="*"),1,),)+ IF(LEN($AE$2),IF(OR($AE$2=AE3,$AE$2="*"),1,),)+ IF(LEN($AF$2),IF(OR($AF$2=AF3,$AF$2="*"),1,),)+ IF(LEN($AG$2),IF(OR($AG$2=AG3,$AG$2="*"),1,),)+ IF(LEN($AH$2),IF(OR($AH$2=AH3,$AH$2="*"),1,),)+ IF(LEN($AI$2),IF(OR($AI$2=AI3,$AI$2="*"),1,),)+ IF(LEN($AJ$2),IF(OR($AJ$2=AJ3,$AJ$2="*"),1,),)+ IF(LEN($AK$2),IF(OR($AK$2=AK3,$AK$2="*"),1,),)+ IF(LEN($AL$2),IF(OR($AL$2=AL3,$AL$2="*"),1,),)+ IF(LEN($AM$2),IF(OR($AM$2=AM3,$AM$2="*"),1,),)+ IF(LEN($AN$2),IF(OR($AN$2=AN3,$AN$2="*"),1,),)+ IF(LEN($AO$2),IF(OR($AO$2=AO3,$AO$2="*"),1,),)+ IF(LEN($AP$2),IF(OR($AP$2=AP3,$AP$2="*"),1,),)+ IF(LEN($AQ$2),IF(OR($AQ$2=AQ3,$AQ$2="*"),1,),)+ IF(LEN($AR$2),IF(OR($AR$2=AR3,$AR$2="*"),1,),)+ IF(LEN($AS$2),IF(OR($AS$2=AS3,$AS$2="*"),1,),)+ IF(LEN($AT$2),IF(OR($AT$2=AT3,$AT$2="*"),1,),)+ IF(LEN($AU$2),IF(OR($AU$2=AU3,$AU$2="*"),1,),)+ IF(LEN($AV$2),IF(OR($AV$2=AV3,$AV$2="*"),1,),)+ IF(LEN($AW$2),IF(OR($AW$2=AW3,$AW$2="*"),1,),)+ IF(LEN($AX$2),IF(OR($AX$2=AX3,$AX$2="*"),1,),)+ IF(LEN($AY$2),IF(OR($AY$2=AY3,$AY$2="*"),1,),)+ IF(LEN($AZ$2),IF(OR($AZ$2=AZ3,$AZ$2="*"),1,),) and here is "Formula Generator" sheet for that
DISTINCT, MAX and list value from join table
How to combine distinct and max within join table below? Table_details_usage UID | VE_NO | START_MILEAGE | END_MILEAGE ------------------------------------------------ 1 | ASD | 410000 | 410500 2 | JWQ | 212000 | 212350 3 | WYS | 521000 | 521150 4 | JWQ | 212360 | 212400 5 | ASD | 410520 | 410600 Table_service_schedule SID | VE_NO | SV_ONMILEAGE | SV_NEXTMILEAGE ------------------------------------------------ 1 | ASD | 400010 | 410010 2 | JWQ | 212120 | 222120 3 | WYS | 511950 | 521950 4 | JWQ | 212300 | 222300 5 | ASD | 410510 | 420510 How to get display as below (only max value)? Get Max value from Table_service_schedule (SV_NEXTMILEAGE) and Get Max value from Table_details_usage (END_MILEAGE) SID | VE_NO | SV_NEXTMILEAGE | END_MILEAGE -------------------------------------------- 5 | ASD | 420510 | 410600 4 | JWQ | 222300 | 212400 3 | WYS | 521950 | 521150
Something in the lines of: SELECT SID, VE_NO, SV_NEXTMILEAGE, (select max(END_MILEAGE) from Table_details_usage d where d.VE_NO = s.VE_NO) END_MILEAGE FROM Table_service_schedule s WHERE SID = (SELECT max(SID) FROM Table_service_schedule s2 WHERE s2.VE_NO = s.VE_NO) Probably could need to change the direct value ov SV_NEXTMILEAGE to max as well if the id:s aren't in order...
PSQL code missing
My problem on getting one row shown with two null values. FROM tuotemerkki; tmtunnus | tmnimi | maa ----------+----------+------------- 1 | McCee | Yhdysvallat 2 | KooTek | Italia 3 | Giardino | Italia (3 rows) FROM tuote; ttunnus | tnimi | kuvaus | suositushinta | tmtunnus ---------+-----------------------+--------------------+---------------+---------- 111 | Trimmeri TRCee | tehokas 4-tahtinen | 179.00 | 1 112 | Trimmerisiima Cee | laadukas siima | 6.99 | 1 113 | Moottorisaha MSCee RR | robusti ja raskas | 559.00 | 1 114 | Trimmerisiima Y | yleissiima | 3.99 | 2 115 | Lapio L | kevyt yleislapio | 23.95 | 2 (5 rows) I need to get this selected with the NULL VALUE on giardino from tmnimi. tmnimi | tnimi | kuvaus ----------+-----------------------+-------------------- McCee | Trimmeri TRCee | tehokas 4-tahtinen McCee | Trimmerisiima Cee | laadukas siima McCee | Moottorisaha MSCee RR | robusti ja raskas KooTek | Trimmerisiima Y | yleissiima KooTek | Lapio L | kevyt yleislapio Giardino | | (6 rows) I get only this selected SELECT tmnimi, tnimi, kuvaus FROM tuote CROSS JOIN tuotemerkki WHERE tuote.tmtunnus = tuotemerkki.tmtunnus; tmnimi | tnimi | kuvaus --------+-----------------------+-------------------- McCee | Trimmeri TRCee | tehokas 4-tahtinen McCee | Trimmerisiima Cee | laadukas siima McCee | Moottorisaha MSCee RR | robusti ja raskas KooTek | Trimmerisiima Y | yleissiima KooTek | Lapio L | kevyt yleislapio (5 rows)
Use a left join between the two tables: SELECT t1.tmnimi, t2.tnimi, t2.kuvaus FROM tuotemerkki t1 LEFT JOIN tuote t2 ON t1.tmtunnus = t2.tmtunnus When you left join from tuotemerkki to tuote, then every record in the former table is guaranteed to appear in the result set. Since the Giardino record does not match to anything in the tuote table, all the columns from that table would have a NULL value for the Giardino record.
Finding root of a tree in a directed graph
I have a tree structure like node(1)->node(2)->node(3). I have name as an property used to retrieve a node. Given a node say node(3), i wanna retrieve node(1). Query tried : MATCH (p:Node)-[:HAS*]->(c:Node) WHERE c.name = "node 3" RETURN p LIMIT 5 But, not able to get node 1.
Your query will not only return "node 1", but it should at least include one path containing it. It's possible to filter the paths to only get the one traversing all the way to the root, however: MATCH (c:Node {name: "node 3"})<-[:HAS*0..]-(p:Node) // The root does not have any incoming relationship WHERE NOT (p)<-[:HAS]-() RETURN p Note the use of the 0 length, which matches all cases, including the one where the start node is the root. Fun fact: even if you have an index on Node:name, it won't be used (unless you're using Neo4j 3.1, where it seems to be fixed since 3.1 Beta2 at least) and you have to explicitly specify it. MATCH (c:Node {name: "node 3"})<-[:HAS*0..]-(p:Node) USING INDEX c:Node(name) WHERE NOT (p)<-[:HAS]-() RETURN p Using PROFILE on the first query (with a numerical id property instead of name): +-----------------------+----------------+------+---------+-------------------------+----------------------+ | Operator | Estimated Rows | Rows | DB Hits | Variables | Other | +-----------------------+----------------+------+---------+-------------------------+----------------------+ | +ProduceResults | 0 | 1 | 0 | p | p | | | +----------------+------+---------+-------------------------+----------------------+ | +AntiSemiApply | 0 | 1 | 0 | anon[23], c -- p | | | |\ +----------------+------+---------+-------------------------+----------------------+ | | +Expand(All) | 1 | 0 | 3 | anon[58], anon[67] -- p | (p)<-[:HAS]-() | | | | +----------------+------+---------+-------------------------+----------------------+ | | +Argument | 1 | 3 | 0 | p | | | | +----------------+------+---------+-------------------------+----------------------+ | +Filter | 1 | 3 | 3 | anon[23], c, p | p:Node | | | +----------------+------+---------+-------------------------+----------------------+ | +VarLengthExpand(All) | 1 | 3 | 5 | anon[23], p -- c | (c)<-[:HAS*]-(p) | | | +----------------+------+---------+-------------------------+----------------------+ | +Filter | 1 | 1 | 3 | c | c.id == { AUTOINT0} | | | +----------------+------+---------+-------------------------+----------------------+ | +NodeByLabelScan | 3 | 3 | 4 | c | :Node | +-----------------------+----------------+------+---------+-------------------------+----------------------+ Total database accesses: 18 and on the second one: +-----------------------+----------------+------+---------+-------------------------+------------------+ | Operator | Estimated Rows | Rows | DB Hits | Variables | Other | +-----------------------+----------------+------+---------+-------------------------+------------------+ | +ProduceResults | 0 | 1 | 0 | p | p | | | +----------------+------+---------+-------------------------+------------------+ | +AntiSemiApply | 0 | 1 | 0 | anon[23], c -- p | | | |\ +----------------+------+---------+-------------------------+------------------+ | | +Expand(All) | 1 | 0 | 3 | anon[81], anon[90] -- p | (p)<-[:HAS]-() | | | | +----------------+------+---------+-------------------------+------------------+ | | +Argument | 1 | 3 | 0 | p | | | | +----------------+------+---------+-------------------------+------------------+ | +Filter | 1 | 3 | 3 | anon[23], c, p | p:Node | | | +----------------+------+---------+-------------------------+------------------+ | +VarLengthExpand(All) | 1 | 3 | 5 | anon[23], p -- c | (c)<-[:HAS*]-(p) | | | +----------------+------+---------+-------------------------+------------------+ | +NodeUniqueIndexSeek | 1 | 1 | 2 | c | :Node(id) | +-----------------------+----------------+------+---------+-------------------------+------------------+ Total database accesses: 13