Postgis using contains and count even if answer is 0 - postgresql

I have a problem with the count function...
I want to isolate all polygons laying beside G10 polygon and I want to count number of points (subway stations) in my polygons (neighborhoods) but i want to receive an answer even if that answer must be 0.
I used the following statement :
select a2.name, count(m.geom)
from arr a1, arr a2, metro m
where n1.code='G10'
and ((st_touches(a1.geom, a2.geom)) or
(st_overlaps(a1.geom, a2.geom)))
and ST_Contains(a2.geom, s.geom)
group by a2.name, m.geom
I know the problem lies with the and ST_Contains(a2.geom, s.geom) part of the where clause, but I do not now how to solve it!

Use an explicit LEFT JOIN:
SELECT a1.name, COUNT(a2.code)
FROM arr a1
LEFT JOIN
arr a2
ON ST_Intersects(a1.geom, a2.geom)
WHERE a1.code = 'G10'
I'm not including the other tables as you have obvious typos in your original query and it's not clear how should they be connected

Related

How to create a functional or where clause from a list of where clauses in kdb?

I have the following where clauses :
q)).tst.wc
(max$["b"];((/:;like);`Col1;(enlist;"0009D000";"00080000")))
(like;`Col2;,"B0000000999")
I want to crate the following query:
,(|;(max$["b"];((/:;like);`Col1;(enlist;"0009D000";"00080000")));(like;`Col2;,"B0000000999"))
I tried
(or;.tst.wc) //doesn't work
(or; first each .tst.wc) // doesn't work
(or;.tst.wc 0;.tst.wc 1) // works
however I cannot use the last one because I don't know how many where clauses will be there. Any suggestions?
You can just append them to or as follows:
q)(or),.tst.wc
|
($["b"];((/:;like);`Col1;(enlist;"0009D000";"00080000")))
(like;`Col2;,"B0000000999")
q)(or;.tst.wc 0;.tst.wc 1)~(or),.tst.wc
1b
EDIT: if you have an unknown number of where clauses and they all need an "or" between them all then you can use:
(or;;)/[.tst.wc]
however this where clause will fast become inefficient as nested "or"s are not optimal query filtering - each clause needs to be applied to the entire length of the table
so the best I could find so far was :
{[x;y]$[x~();(or;y);x,enlist y]}/[();.tst.wc]
... ready to accept and upvote a better answer ...
What about using any? If I understand you correctly you are creating any number of or conditions.
t:([]a:til 10;b:`a`b`c`d`e`f`g`h`i`j;c:10*til 10);
.tst.wc:((=;`a;0);(=;`b;enlist `d);(=;`c;90));
?[t;enlist ((any),enlist (enlist),.tst.wc);0b;()!()]
a b c
------
0 a 0
3 d 30
9 j 90
// also works with one
.tst.wc2:enlist (=;`a;0);
?[t;enlist ((any),enlist (enlist),.tst.wc2);0b;()!()]
a b c
-----
0 a 0

Write a Q-SQL query to multiply the price of BA.N by 2, GS.N by 3 and MSFT.O by 4 and call the column newPrice using vector conditional statement

Write a Q-SQL query to multiply the price of BA.N by 2, GS.N by 3 and MSFT.O by 4 and call the column newPrice using vector conditional statement
tab2:`syms`prices!(`MSFT.O`GS.N`BA.N;45.15 191.10 178.50)
flip tab2
select syms,prices,newPrice:(prices*(4,3,2)) from flip tab2
I'm not sure using a vector conditional would be the easiest way to go about this. For example, you could use a simple dictionary to achieve a similar effect. First define a dictionary mapping your syms to their multipliers then use that dictionary in your select statement:
tab2: flip `syms`prices!(`MSFT.O`GS.N`BA.N;45.15 191.10 178.50)
d: `MSFT.O`GS.N`BA.N!4 3 2;
select syms, prices, newPrice: prices*d[syms] from tab2
syms prices newPrice
----------------------
MSFT.O 45.15 180.6
GS.N 191.1 573.3
BA.N 178.5 357
Vector conditionals can only return one of two results, depending on if the condition is true or false. To extend that limitation to what you want you could nest the conditionals inside each other. So like:
select syms, prices, newPrice: ?[syms=`MSFT.O; prices*4; ?[syms=`GS.N; prices*3; ?[syms=`BA.N;prices*2;prices]]] from tab2
But this quickly becomes unwieldy and doesn't scale well. If you added more syms, it would be easy to update the dictionary, but annoying to update the conditional.
You should create multipliers map
(`MSFT.O`GS.N`BA.N!2 3 4)
and multiply each price on value from the map based on row syms:
update newPrice: prices*(`MSFT.O`GS.N`BA.N!2 3 4)syms from flip tab2

SQL query to include V and E props in the result

I feel like this should be simple, but lots of searching and experimenting has not produced any results.
I have a very simple ODB database with one V and one E class. V has various props and E has one prop: "order"
This simple ODB SQL query...
select expand(out()) from #12:34
...returns all the props from the V records connected by the "out" edges on #12:34 (i.e. the child records of #12:34), working as expected.
But what I'm not able to do is to also include the one prop from those edges, as well as sort by that E prop (which should be trivial once I can get it into the projections).
This works fine in OrientDB v 3.0.0RC2 (the GA will be released in a few days)
MATCH
{class:V, where:(#rid = ?), as:aVertex}.outE(){as:theEdge}.inV(){as:otherVertex}
RETURN theEdge:{*}, otherVertex:{*}
you can also return single properties with
RETURN theEdge.prop1 as p1, theEdge.prop2 as p2, otherVertex.propX as p3

Cannot mix aggregate and non-aggregate comparison with COUNT

I know this is very commom question. But I havenot still known why in my case as follows. Give me your idea about this issue:
Question: I want to count the number of user who appear in list < 3.
- First I created the "calculated Field"
- Here is my function:
If COUNT([User]) < 3 then [User] END
Finally, I count this Meseasure again to gain the final result.
Here's my example:
User
a
a
a
a
b
b
c
b
The result expected: 1 (only c)
Thanks all
Place your IF statement inside the COUNT().

How to extract year from a dates cell array in MATLAB?

i have a cell array as below, which are dates. I am wondering how can i extract the year at the last 4 digits? Could anyone teach me how to locate the year in the string? Thank you!
'31.12.2001'
'31.12.2000'
'31.12.2004'
'31.12.2003'
'31.12.2002'
'31.12.2000'
'31.12.1999'
'31.12.1998'
'31.12.1997'
'31.12.2005'
'31.12.2004'
'31.12.2003'
'31.12.2002'
'31.12.2001'
'31.12.2000'
'31.12.1999'
'31.12.1998'
'31.12.2005'
'31.12.2004'
'31.12.2003'
'31.12.2002'
'31.12.2005'
Example cell array:
A = {'31.12.2001'; '31.12.2002'; '31.12.2003'};
Apply some regular expressions:
B = regexp(A, '\d\d\d\d', 'match')
B = [B{:}];
EDIT: I never realized that matlab will "nest" an extra layer of cells until I tested this. I don't like this solution as much now that I know the second line is necessary. Here is an alternative approach that gets you the years in numeric form:
C = datevec(A, 'dd.mm.yyyy');
C = C(:, 1);
SECOND EDIT: Suprisingly, if your cell array has less than 10000 elements, the regexp approach is faster on my machine. But the output of it is another cell array (which takes up much more memory than a numeric matrix). You can use B = cell2mat(B) to get a character array instead, but this brings the two approaches to approximately equal efficiency.
Just to add a fun answer, designed to take the OP to the stranger regions of Matlab:
C = char(C);
y = (D(:,7:end)-'0') * 10.^(3:-1:0).'
which is an order of magnitude faster than anything posted in the other answers :)
Or, to stay a bit closer to home,
y = cellfun(#(x)str2double(x(7:end)),C);
or, yet another regexp variation:
y = str2num(char(regexprep(C, '\d+\.\d+\.','')));
Assuming your matrix with dates is M or a cell array C:
In case your data is in a cell array start with
M = cell2mat(C)
Then get the relevant part
Y=M(:,end-4:end)
If required you can even make the year a number
Year = str2num(Y)
Using regexp this will works also with dates with slightly different formats, like 1.1.2000, which can mess with you offsets
res = regexp(dates, '(?<=\d+\.\d+\.)\d+', 'match')