Returning boolean values in sparql - boolean

From the rdf file, I need to return true for the person if their age is even, false if their age is odd. I wrote the query to display persons with even age, but need to modify to display the results in boolean values.
select * where { ?x h:age ?age .
filter( strends(?age, 0) || strends(?age, 2) || strends(?age, 4) || strends(?age, 6) || strends(?age, 8) )
}

an even test is ?X/2 = FLOOR(?X/2).
So if ?age has a numeric datatype:
where { ?x h:age ?age .
BIND( (?age/2 = FLOOR(?age/2)) AS ?isEven)
}
will add ?isEven as true/false.
If ?age is a string, then replace ?age with xsd:integer(?age).

I had a similar case. I needed to return in the results true/false if the optional relationship exists.
SELECT ?c ?hasNarrowMatch
WHERE {
?c a skos:Concept.
OPTIONAL {?c skos:narrowMatch ?nm}
BIND (exists{?c skos:narrowMatch ?nm} AS ?y)
BIND (IF(?y, "true", "false") AS ?hasNarrowMatch)
}
The results will look like this:
+-----+----------------+
| c | hasNarrowMatch |
+-----+----------------+
| c1 | true |
| c2 | false |
| c3 | true |
+-----+----------------+

Related

Antlr4 can't recognize a single number and bracket. I don't know what the problem is?

lexer grammar TransformLexer;
#header { package com.abc.g4.gen; }
channels { DPCOMMENT, ERRORCHANNEL }
#members {
/**
* Verify whether current token is a valid decimal token (which contains dot).
* Returns true if the character that follows the token is not a digit or letter or underscore.
*
* For example:
* For char stream "2.3", "2." is not a valid decimal token, because it is followed by digit '3'.
* For char stream "2.3_", "2.3" is not a valid decimal token, because it is followed by '_'.
* For char stream "2.3W", "2.3" is not a valid decimal token, because it is followed by 'W'.
* For char stream "12.0D 34.E2+0.12 " 12.0D is a valid decimal token because it is folllowed
* by a space. 34.E2 is a valid decimal token because it is followed by symbol '+'
* which is not a digit or letter or underscore.
*/
public boolean isValidDecimal() {
int nextChar = _input.LA(1);
if (nextChar >= 'A' && nextChar <= 'Z' || nextChar >= '0' && nextChar <= '9' ||
nextChar == '_') {
return false;
} else {
return true;
}
}
}
// SKIP
SPACE: [ \t\r\n]+ -> channel(HIDDEN);
SPEC_MYSQL_COMMENT: '/*!' .+? '*/' -> channel(DPCOMMENT);
COMMENT_INPUT: '/*' .*? '*/' -> channel(HIDDEN);
LINE_COMMENT: (
('--' [ \t] | '#') ~[\r\n]* ('\r'? '\n' | EOF)
| '--' ('\r'? '\n' | EOF)
) -> channel(HIDDEN);
STRING
: DQUOTA_STRING
;
EQ : '==';
NEQ : '<>';
NEQJ: '!=';
LT : '<';
LTE : '<=';
GT : '>';
GTE : '>=';
PLUS: '+';
MINUS: '-';
ASTERISK: '*';
SLASH: '/' ;
PERCENT: '%';
RSHIFT: '>>';
LSHIFT: '<<';
IS: 'IS' | 'is';
NULL: 'NULL' | 'null';
TRUE: 'TRUE' | 'true';
FALSE: 'FALSE' | 'false';
LIKE: 'LIKE' | 'like';
OR: 'OR' | 'or' | '|';
AND: 'AND' | '&&' | 'and' | '&';
IN: 'IN' | 'in';
NOT: 'NOT' | '!' | 'not';
CASE: 'CASE' | 'case';
WHEN: 'WHEN' | 'when';
THEN: 'THEN' | 'then';
ELSE: 'ELSE' | 'else';
END: 'END' | 'end';
JOIN: '||';
ID: [#]ID_LITERAL+;
// DOUBLE_QUOTE_ID: '"' ~'"'+ '"';
REVERSE_QUOTE_ID: '`' ~'`'+ '`';
NAME: ID_LITERAL+;
fragment ID_LITERAL: [a-zA-Z_0-9\u0080-\uFFFF]*?[a-zA-Z_$\u0080-\uFFFF]+?[a-zA-Z_$0-9\u0080-\uFFFF]*;
fragment DQUOTA_STRING: '"' ( '\\'. | '""' | ~('"'| '\\') )* '"' | '\'' ( ~('\''|'\\') | ('\\' .) )* '\'';
fragment DEC_DIGIT: '0' .. '9'+;
// Last tokens must generate Errors
ERROR_RECONGNIGION: . -> channel(ERRORCHANNEL);
NEWLINE:'\r'? '\n' ;
BYTELENGTH_LITERAL
: DEC_DIGIT+ ('B' | 'K' | 'M' | 'G')
;
INTEGER_VALUE
: [-]*DEC_DIGIT+
;
DECIMAL_VALUE
: DEC_DIGIT+ EXPONENT
| DECIMAL_DIGITS EXPONENT? {isValidDecimal()}?
;
IDENTIFIER
: (LETTER | DEC_DIGIT | '_')+
;
BACKQUOTED_IDENTIFIER
: '`' ( ~'`' | '``' )* '`'
;
COMMA: ',' ;
LEFT_BRACKET
: '(('
;
RGIHT_BRACKET
: '))'
;
LEFT_BRACKET1
: '{{'
;
RGIHT_BRACKET1
: '}}'
;
START
: '$'
;
fragment DECIMAL_DIGITS
: DEC_DIGIT+ '.' DEC_DIGIT+
| '.' DEC_DIGIT+
;
fragment EXPONENT
: 'E' [+-]? DEC_DIGIT+
;
fragment LETTER
: [A-Z]
;
SIMPLE_COMMENT
: '--' ~[\r\n]* '\r'? '\n'? -> channel(HIDDEN)
;
BRACKETED_COMMENT
: '/*' .*? '*/' -> channel(HIDDEN)
;
WS
: [ \r\n\t]+ -> channel(HIDDEN)
;
parser grammar TransformParser;
options { tokenVocab=TransformLexer; }
#header { package com.abc.g4.gen; }
finalExpression:
(booleanExpression | caseExpression | resultExpression | function) EOF
;
caseExpression
: CASE whenClause+ (ELSE (elseExpression=resultExpression | caseExpression))? END #whenExpression
| constant #constantDefault
;
values:
constant #constantValue
| ID #idValue
;
valueCalc:
LEFT_BRACKET valueCalc RGIHT_BRACKET
| valueCalc ('*'|'/'|'%') valueCalc
| valueCalc ('+'|'-') valueCalc
| valueCalc ('<<'|'>>') valueCalc
| values
;
booleanExpression
: left=booleanExpression operator=AND right=booleanExpression #logicalBinary1
| left=booleanExpression operator=OR right=booleanExpression #logicalBinary
| NOT booleanExpression #logicalNot
| predicated #predicatedExpression
| left=valueCalc operator=comparisonOperator right=valueCalc #comparison4
| booleanValue #booleanValueTag
;
predicated
: (values | valueCalc) IN values (values)*
;
whenClause:
WHEN condition=booleanExpression THEN (result=resultExpression | caseExpression);
resultExpression:
predicated | values | valueCalc;
constant
: NULL #nullLiteral
| STRING #typeConstructor
| number #numericLiteral
| booleanValue #booleanLiteral
| STRING+ #stringLiteral
;
comparisonOperator
: EQ | NEQ | NEQJ | LT | LTE | GT | GTE | IS
;
booleanValue
: TRUE | FALSE
;
number
: MINUS? DECIMAL_VALUE #decimalLiteral
| MINUS? INTEGER_VALUE #integerLiteral
;
qualifiedName
: NAME
;
function
: qualifiedName (params) #functionCall
;
param:
valueCalc | values | function | booleanExpression
;
params:
param (param)*
;
I can recognize numbers of multiple characters, but I cannot recognize numbers of single characters
enter image description here
enter image description here
And parentheses cannot change the priority of expression calculation. What's wrong with my code
enter image description here
I try to replace '(', ')' with '((', '))' or '{{', '}}'. It can be done
enter image description here
Resolved: delete 'ERROR_ RECONGNATION 'Then it's OK

Postgres returning empty result if one of the outcome is null

Postgres returning empty result if one of the outcome is null.
For a scenario, consider a table,
table: books
id | title | is_free |
1 | A | true |
2 | B | false |
select 'some_text' as col, b.title
from (select title from books
where id = 3) as b;
In this case, the number of rows returned is 0.
col | title |
(0 rows)
How to return Null as return value?
col | title |
some_text | NULL |
(1 row)
Use a subquery in a different way:
select 'some_text' as col,
(select title from books where id = 3);

How to apply an empty condition to sql select by using "and" in Spark?

I have an UuidConditionSet, when the if condition is wrong, I want apply an empty string to my select statement(or just ignore this UuidConditionSet), but I got this error. How to solve this problem?
mismatched input 'FROM' expecting <EOF>(line 10, pos 3)
This is the select
(SELECT
item,
amount,
date
from my_table
where record_type = 'myType'
and ( date_format(date, "yyyy-MM-dd") >= '2020-02-27'
and date_format(date, "yyyy-MM-dd") <= '2020-02-28' )
and ()
var UuidConditionSet = ""
var UuidCondition = Seq.empty[String]
if(!UuidList.mkString.isEmpty) {
UuidCondition = for {
Uuid <- UuidList
UuidConditionSet = s"${SQLColumnHelper.EVENT_INFO_STRUCT_NAME}.${SQLColumnHelper.UUID} = '".concat(eventUuid).concat("'")
} yield UuidConditionSet
UuidConditionSet = UuidCondition.reduce(_.concat(" or ").concat(_))
}
s"""SELECT
| ${SQLColumnHelper.STRUCT_NAME_ITEM},
| ${SQLColumnHelper.STRUCT_NAME_AMOUNT},
| ${SQLColumnHelper.DATE}
| from ${sqlTableHelper.TABLE}
| where ${SQLColumnHelper.EVENT_INFO_STRUCT_NAME} = '${RECORD_TYPE}'
| and ( date_format(${SQLColumnHelper.DATE}, "${Constant.STAY_DATE_FORMAT}") >= '${stayDateRangeTuple._1}'
| and date_format(${SQLColumnHelper.DATE}, "${Constant.STAY_DATE_FORMAT}") <= '${stayDateRangeTuple._2}' )
| and ($UuidConditionSet)
You can use pattern matching on the list UuidList to check the size and return an empty string if the list is empty. Also, you can use IN instead of multiple ORs here.
Try this:
val UuidCondition = UuidList match {
case l if (l.size > 0) => {
l.map(u => s"'$u'").mkString(
s"and ${SQLColumnHelper.EVENT_INFO_STRUCT_NAME}.${SQLColumnHelper.UUID} in (",
",",
")"
)
}
case _ => ""
}
s"""SELECT
| ${SQLColumnHelper.STRUCT_NAME_ITEM},
| ${SQLColumnHelper.STRUCT_NAME_AMOUNT},
| ${SQLColumnHelper.DATE}
| from ${sqlTableHelper.TABLE}
| where ${SQLColumnHelper.EVENT_INFO_STRUCT_NAME} = '${RECORD_TYPE}'
| and date_format(${SQLColumnHelper.DATE}, "${Constant.STAY_DATE_FORMAT}") >= '${stayDateRangeTuple._1}'
| and date_format(${SQLColumnHelper.DATE}, "${Constant.STAY_DATE_FORMAT}") <= '${stayDateRangeTuple._2}'
| $UuidCondition
"""

Scala Slick: Getting number of fields with a specific value in a group by query

I have a table like this:
|``````````````````````````|
|imgId, pageId, isAnnotated|
|1, 1, true |
|2, 1, false |
|3, 2, true |
|4, 1, false |
|5, 3, false |
|6, 2, true |
|7, 3, true |
|8, 3, true |
|__________________________|
I want the result as:
|`````````````````````````````````````|
|pageId, imageCount, noOfAnotatedImage|
| 1 3 1 |
| 2 2 2 |
| 3 3 2 |
|_____________________________________|
I want the number of annotated images based on number field set as true.
Slick related code I tried which fired exception:
def get = {
val q = (for {
c <- WebImage.webimage
} yield (c.pageUrl, c.lastAccess, c.isAnnotated)).groupBy(a => (a._1, a._3)).map{
case(a,b) => (a._1, b.map(_._2).max, b.filter(_._3 === true).length, b.length)
}
db.run(q.result)
}
Exception:
[SlickTreeException: Cannot convert node to SQL Comprehension
| Path s6._2 : Vector[t2<{s3: String', s4: Long', s5: Boolean'}>]
]
Note: This Count the total records containing specific values thread clear shows that in plain SQL what I need is possible.
SELECT
Type
,sum(case Authorization when 'Accepted' then 1 else 0 end) Accepted
,sum(case Authorization when 'Denied' then 1 else 0 end) Denied
from MyTable
where Type = 'RAID'
group by Type
Changed the code but still getting exception:
Execution exception
[SlickException: No type for symbol s2 found for Ref s2]
In /home/ravinder/IdeaProjects/structurer/app/scrapper/Datastore.scala:60
56 def get = {
57 val q = (for {
58 c <- WebImage.webimage
59 } yield (c.pageUrl, c.lastAccess, c.isAnnotated)).groupBy(a => (a._1, a._3)).map{
[60] case(a,b) => (a._1, b.map(_._2).max, b.map(a => if (a._3.result == true) 1 else 0 ).sum, b.length)
61 }
62 db.run(q.result)
63 }
64
Given your requirement, you should group by only pageUrl so as to perform aggregation over all rows for the same page. You can aggregate lastAccess using max and isAnnotated using sum over a conditional Case.If-Then-Else. The Slick query should look something like the following:
val q = (for {
c <- WebImage.webimage
} yield (c.pageUrl, c.lastAccess, c.isAnnotated)).
groupBy( _._1 ).map{ case (url, grp) =>
val lastAcc = grp.map( _._2 ).max
val annoCnt = grp.map( _._3 ).map(
anno => Case.If(anno === true).Then(1).Else(0)
).sum
(url, lastAcc, annoCnt, , grp.length)
}

PostgreSQL JSONB query types of each keys

I have certain table:
CREATE TABLE x(
id BIGSERIAL PRIMARY KEY,
data JSONB
);
INSERT INTO x(data)
VALUES( '{"a":"test", "b":123, "c":null, "d":true}' ),
( '{"a":"test", "b":123, "c":null, "d":"yay", "e":"foo", "f":[1,2,3]}' );
How to query types of each key in that table, so it would give an output something like this:
a | string:2
b | number:2
c | null:2
d | boolean:1 string:1
e | string:1
f | jsonb:1 -- or anything
I only know the way to get the keys and count, but don't know how to get the type of each key:
SELECT jsonb_object_keys(data), COUNT(id) FROM x GROUP BY 1 ORDER BY 1
that would give something like:
a | 2
b | 2
c | 2
d | 2
e | 1
f | 1
EDIT:
As pozs points out, there are two typeof functions: one for JSON and one for SQL. This query is the one you're looking for:
SELECT
json_data.key,
jsonb_typeof(json_data.value),
count(*)
FROM x, jsonb_each(x.data) AS json_data
group by key, jsonb_typeof
order by key, jsonb_typeof;
Old Answer: (Hey, it works...)
This query will return the type of the keys:
SELECT
json_data.key,
pg_typeof(json_data.value),
json_data.value
FROM x, jsonb_each(x.data) AS json_data;
... unfortunately, you'll notice that Postgres doesn't differentiate between the different JSON types. it regards it all as jsonb, so the results are:
key1 | value1 | value
------+--------+-----------
a | jsonb | "test"
b | jsonb | 123
c | jsonb | null
d | jsonb | true
a | jsonb | "test"
b | jsonb | 123
c | jsonb | null
d | jsonb | "yay"
e | jsonb | "foo"
f | jsonb | [1, 2, 3]
(10 rows)
However, there aren't that many JSON primitive types, and the output seems to be unambiguous. So this query will do what you're wanting:
with jsontypes as (
SELECT
json_data.key AS key1,
CASE WHEN left(json_data.value::text,1) = '"' THEN 'String'
WHEN json_data.value::text ~ '^-?\d' THEN
CASE WHEN json_data.value::text ~ '\.' THEN 'Number'
ELSE 'Integer'
END
WHEN left(json_data.value::text,1) = '[' THEN 'Array'
WHEN left(json_data.value::text,1) = '{' THEN 'Object'
WHEN json_data.value::text in ('true', 'false') THEN 'Boolean'
WHEN json_data.value::text = 'null' THEN 'Null'
ELSE 'Beats Me'
END as jsontype
FROM x, jsonb_each(x.data) AS json_data -- Note that it won't work if we use jsonb_each_text here because the strings won't have quotes around them, etc.
)
select *, count(*) from jsontypes
group by key1, jsontype
order by key1, jsontype;
Output:
key1 | jsontype | count
------+----------+-------
a | String | 2
b | Integer | 2
c | Null | 2
d | Boolean | 1
d | String | 1
e | String | 1
f | Array | 1
(7 rows)
You can improve your last query with jsonb_typeof
with jsontypes as (
SELECT
json_data.key AS key1,
jsonb_typeof(json_data.value) as jsontype
FROM x, jsonb_each(x.data) AS json_data
)
select *, count(*)
from jsontypes
group by 1, 2
order by 1, 2;