I'm working in Access 2010. I want NULL values to return as 0 but I cannot get them to show up. The false values work fine. There should be 29 total rows, 20 returning 0 and 9 returning their value. Here is the code.
SELECT [QAT Export].Title, IIF(ISNULL(Count([QAT Export].[TaskID])),0,Count([QAT Export].[Task ID])) AS [Update Good]
FROM [QAT Export]
WHERE ((([QAT Export].[Task Status])<>"Closed" And ([QAT Export].[Task Status])<>"Cancelled") AND (([QAT Export].[Updated By]) <>"linker")AND((DateDiff("d",[Update Time],(Date())))<10))
GROUP BY [QAT Export].Title
ORDER BY [QAT Export].Title;
Your IIF() and IsNull() functions look fine.
Chances are: your WHERE clause is excluding the nulls through one of the tests in there.
What are the chances since [TaskID] is Null, [Task Status] is Null as well?
If that's the case, you'd need to test for IsNull([Task Status]) in your WHERE clause also.
Post your 29 records if you need more help. Most likely the Data is causing your WHERE clause to drop those records.
Related
I have a bitmask (really a 'flagmask') of integer values (1, 2, 4, 8, 16 etc.) which apply to a field and I need to store this in a (text) log file. What I effectively store is something like "x=296" which indicates that for field "x", flags 256, 32 and 8 were set.
When searching the logs, how can I easily search this text string ("x=nnn") and determine from the value of "nnn" whether a specific flag was set? For instance, how could I look at the number and know that flag 8 was set?
I know this is a somewhat trivial question if we're doing 'true' bitmask processing, but I've not seen it asked this way before - the log searching will just be doing string matching, so it just sees a value of "296" and there is no way to convert it to its constituent flags - we're just using basic string searching with maybe some easy SQL in there.
Your best bet is to do full string regex matching.
For bit 8 set, do this:
SELECT log_line
FROM log_table
WHERE log_line
RLIKE 'x=(128|129|130|131|132|133|134|135|136|137|138|139|140|141|142|143|144|145|146|147|148|149|150|151|152|153|154|155|156|157|158|159|160|161|162|163|164|165|166|167|168|169|170|171|172|173|174|175|176|177|178|179|180|181|182|183|184|185|186|187|188|189|190|191|192|193|194|195|196|197|198|199|200|201|202|203|204|205|206|207|208|209|210|211|212|213|214|215|216|217|218|219|220|221|222|223|224|225|226|227|228|229|230|231|232|233|234|235|236|237|238|239|240|241|242|243|244|245|246|247|248|249|250|251|252|253|254|255)[^0-9]'
Or simplified to:
RLIKE 'x=(12[89]|1[3-9][0-9]|2[0-4][0-9]|25[0-5])[^0-9]'
The string x= must exist in the logs followed by the decimal number and a non decimal after the number.
For bit 2 set, do this:
SELECT log_line FROM log_table WHERE log_line RLIKE 'x=(2|3|6|7|10|11|14|15|18|19|22|23|26|27|30|31|34|35|38|39|42|43|46|47|50|51|54|55|58|59|62|63|66|67|70|71|74|75|78|79|82|83|86|87|90|91|94|95|98|99|102|103|106|107|110|111|114|115|118|119|122|123|126|127|130|131|134|135|138|139|142|143|146|147|150|151|154|155|158|159|162|163|166|167|170|171|174|175|178|179|182|183|186|187|190|191|194|195|198|199|202|203|206|207|210|211|214|215|218|219|222|223|226|227|230|231|234|235|238|239|242|243|246|247|250|251|254|255)[^0-9]'
I test the bit2 on some live data:
SELECT count(log_line)
...
count(log_line)
128
1 row in set (0.002 sec)
Much depends on how "easy" the "easy SQL" must be.
If you can use string splitting to separate "X" from "296", then using AND with the value 296 is easy.
If you cannot, then, as you observed, 296 yields no traces of its 8th bit state. You'd need to check for all the values that have the 8th bit set, and of course that means exactly half of the available values. You can compress the regexp somewhat:
248 249 250 251 252 253 254 255 => 24[89]|25[0-5]
264 265 266 267 268 269 270 271 => 26[4-9]|27[01]
280 281 282 283 284 285 286 287 => 28[0-7]
296 297 298 299 300 301 302 303 => 29[6-9]|30[1-3]
...24[89]|25[0-5]|26[4-9]|27[01]|28[0-7]|29[6-9]|30[1-3]...
but I think that the evaluation tree won't change very much, this kind of optimization is already present in most regex engines. Performances are going to be awful.
If at all possible I would try to rework the logs (maybe with a filter) to rewrite them as "X=000100101000b" or at least "X=0128h". The latter hexadecimal would allow you to search for bit 8 looking for "X=...[89A-F]h" only.
I have several times had to do changes like these - it involves preparing a pipe filter to create the new logs (it is more complicated if the logging process writes straight to a file - at worst, you might be forced to never run searches on the current log file, or to rotate the logs when such a search is needed), then slowly during low-load periods the old logs are retrieved, decompressed, reparsed, recompressed, and stored back. It's long and boring, but doable.
For database-stored logs, it's much easier and you can even avoid any alterations to the process that does the logs - you add a flag to the rows to be converted, or persist the timestamps of the catch-up conversion:
SELECT ... FROM log WHERE creation > lowWaterMark ORDER BY creation DESC;
SELECT ... FROM log WHERE creation < highWaterMark ORDER BY creation ASC;
the retrieved rows are updated, and the appropriate watermarkers are updated with the last creation value that has been retrieved. The "lowWaterMark" pursues the logging process. This way you only can't search from the current instant down to lowWaterMark, which will "lag" behind (ultimately, just a few seconds, except under heavy load).
One way to determine if a specific flag is set in the value "nnn" is to use bitwise operators to check if the flag is present in the value. For eg. to check if flag 8 is set in the value 296, you can use the bitwise AND operator to check if the value of 8 is present:
if (nnn & 8) == 8:
print("flag 8 is set")
Another method I can think of would be to check if the value of flag 8 is present in the log string "x=nnn" by using regular expressions, where you search for the string "8" in the log.
import re
log_string = "x=296"
if re.search("8", log_string):
print("flag 8 is set")
You could also use a function that takes the log string and flag as input and returns a boolean indicating whether the flag is set in the log string.
def check_flag(log_string, flag):
nnn = int(log_string.split('=')[1])
return (nnn & flag) == flag
if check_flag("x=296", 8):
print("flag 8 is set")
use a bitwise operator & to check if a specific flag is set in the value
function hasFlag(value, flag) {
return (value & flag) === flag;
}
const value = 296;
console.log(hasFlag(value, 256)); // true
console.log(hasFlag(value, 32)); // true
console.log(hasFlag(value, 8)); // true
console.log(hasFlag(value, 4)); // false
I'm making a flight tracking map that will need to pull live data from a sql lite db. I'm currently just using the sqlite executable to navigate the db and understand how to interact with it. Each aircraft is identified by a unique hex_ident. I want to get a list of all aircraft that have sent out a signal in the last minute as a way of identifying which aircraft are actually active right now. I tried
select distinct hex_ident, parsed_time
from squitters
where parsed_time >= Datetime('now','-1 minute')
I expected a list of 4 or 5 hex_idents only but I'm just getting a list of every entry (today's entries only) and some are outside the 1 minute bound. I'm new to sql so I don't really know how to do this yet. Here's what each entry looks like. The table is called squitters.
{
"message_type":"MSG",
"transmission_type":8,
"session_id":"111",
"aircraft_id":"11111",
"hex_ident":"A1B4FE",
"flight_id":"111111",
"generated_date":"2021/02/12",
"generated_time":"14:50:42.403",
"logged_date":"2021/02/12",
"logged_time":"14:50:42.385",
"callsign":"",
"altitude":"",
"ground_speed":"",
"track":"",
"lat":"",
"lon":"",
"vertical_rate":"",
"squawk":"",
"alert":"",
"emergency":"",
"spi":"",
"is_on_ground":0,
"parsed_time":"2021-02-12T19:50:42.413746"
}
Any ideas?
You must remove 'T' from the value of parsed_time or use datetime() for it also to make the comparison work:
where datetime(parsed_time) >= datetime('now', '-1 minute')
Note that datetime() function does not take into account microseconds, so if you need 100% accuracy, you must put them in the code with concatenation:
where replace(parsed_time, 'T', ' ') >=
datetime('now', '-1 minute') || substr(parsed_time, instr(parsed_time, '.'))
I'm writing an SQLite select statement and want to pick out the first hit only that satisfy my criterion.
My problem is that I'm writing code inside a simulation framework that wraps my SQLite code before sending it to the database, and this wrapping already adds 'LIMIT 100' to the end of the code.
What I want to do:
SELECT x, y, z FROM myTable WHERE a = 0 ORDER BY y LIMIT 1
What happens when this simulation development framework has done its job:
SELECT x, y, z FROM myTable WHERE a = 0 ORDER BY y LIMIT 1 LIMIT 100
exec error near "LIMIT": syntax error
So my question is: How do I work around this limitation? Is there any way to still limit my results to give only one hit back despite that the statement will end in 'LIMIT 100'? I'm thinking something like creating a temporary table, add an index and filter on that, but my knowledge is limited to simple database queries.
I'm in AX 2012 R2 environment.
I would like to add a query range to HcmEmployment table and filter out rows that have a LegalEntity value = 0.
The following code fails at runtime with the exception "Invalid Range".
qbrLegalEntity = qbds.addRange(fieldNum(HcmEmployment, LegalEntity));
strRangeCondition = '(%1 != %2)';
qbrLegalEntity.value(strFmt(strRangeCondition,
fieldStr(HcmEmployment, LegalEntity),
queryValue("0")));
Is it possible to code this range condition?
Thank you.
Do not make it harder:
qbds.addRange(fieldNum(HcmEmployment,LegalEntity)).value(SysQuery::valueNot(0));
The reason for your failed query expression was the use of queryValue("0") which quotes the zero. Changing that to 0 would work as well, but again too laborious.
And even shorter is:
qbds.addRange(fieldNum(HcmEmployment,LegalEntity)).value('!0');
To diagnose query errors take a look on the SQL generated:
info(qbds.toString());
I have a table such as the following:
mafiadb:{"Etzli":{"alive":50,"mafia":60,"vigilante":3,"doctor":4,"citizen":78,"police":40},"Charneus":{"alive":29,"mafia":42,"vigilante":6,"doctor":14,"citizen":53,"police":33}}
There are more nested tables, but I'm just trying to keep it simple for now.
I run the following code to extract certain values (I'm making an ordered list based on those values):
sortmaf={}
for k,v in pairs(mafiadb) do
sortmaf[k]=v["mafia"]
end
That's one of the codes I run. The problem I'm running into is that it doesn't appear you can do arithmetic in a table loop. I tried:
sortpct={}
for k,v in pairs(mafiadb) do
sortpct[k]=(v["alive"]*100)/(v["mafia"]+v["vigilante"]+v["doctor"]+v["citizen"]+v["police"])
end
It returns that I'm attempting to do arithmetic on field "alive." What am I missing here? As usual, I appreciate any consideration in answering this question!
Editing:
Instead of commenting on the comment, I'm going to add additional information here.
The mafiadb database I've posted IS the real database. It's just stripped down to two players instead of the current 150+ players I have listed in it. It's simply structured as such:
mafiadb = {
Playername = {
alive = 0
mafia = 0
vigilante = 0
doctor = 0
police = 0
citizen = 0
}
}
Add a few hundred more playernames, and there you have it.
As for the error message, the exact message is:
attempt to perform arithmetic on field 'alive' (nil value)
So... I'm not sure what the problem is. In my first code, the one with sortmaf, it works perfectly, but suddenly, it can't find v["alive"] as a value when I'm trying to do arithmetic? If I just put v["alive"] by itself, it's suddenly found and isn't nil any longer. I hope this clarifies a bit more.
This looks like a simple typo to me.
Some of your 150 characters is not well written - probably they don't have an "alive" property, or it's written incorrectly, or it's not a number. Try this:
for k,v in pairs(mafiadb) do
if type(v.alive) ~= 'number' then
print(k, "doesn't have a correct alive property")
end
end
This should print the names of the "bad" characters.