I have written a report and im having a little bother with NULL values.
In my report i had a WHERE clause:
WHERE Cust.Ref LIKE ?
This clause caused issues with another section of my report (Nominal Codes). When i filtered on a nominal code, it returned 0 results where it should have returned 34 results.
I removed the WHERE clause and it worked fine...Great i have found the issue.
I changed my WHERE clause to:
WHERE (Cust.Ref LIKE ? OR Cust.Ref IS NULL)
This fixed the nomincal code issue but now when i filter by a customer reference it also brings back all NULL values.
Can someone please advise?
Thanks.
You can turn the where clause around a bit to check for a null placeholder value.
WHERE (? IS NULL OR Cust.Ref LIKE ?)
Related
I have a database with MANY out-of-date file locations. The difference between the out-of-date file locations and the correct locations is simply the left-side of the address. So, I am attempting to take the left-side off and replace it with the correct string. But, I can't get there because my query is altering the right-side of the address.
This query is made using "vfpoledb."
SELECT RIGHT(LINK,LEN(LINK)-8) ,LEN(LINK)-8,RIGHT(LINK,77),LINK
FROM LINKSTORE
WHERE DOCLBL = "V46145002A"
This query returns the following:
EXP1:
\SHARES\DATA\QMS\QMS DATA\TRACKING FILES\REMOTEENTRIES\V46145 216447
EXP2:
77
EXP3:
\SHARES\DATA\QMS\QMS DATA\TRACKING FILES\REMOTEENTRIES\V46145 216447-002A.PDF
LINK:
\\SERVER\SHARES\DATA\QMS\QMS DATA\TRACKING FILES\REMOTEENTRIES\V46145 216447-002A.PDF
I don't understand why EXP1 and EXP3 are giving different results. EXP3 is what I'm looking for EXP1 to return. If I could get that, I could append the correct left-hand-side and create an update query to fix everything.
Edit:
Even when changing the query to:
SELECT RIGHT(LINK,LEN(LINK)) ,LEN(LINK)-8,RIGHT(LINK,77),LINK
FROM LINKSTORE
WHERE DOCLBL = "V46145002A"
The link still cuts off at the same point, which is odd because expression_3 which still uses Right(), but manually provides the length instead of using Len() does not do this.
Furthermore, it seems that when I run the query to include all results:
SELECT RIGHT(LINK,LEN(LINK)) ,LEN(LINK)-8,RIGHT(LINK,77),LINK
FROM LINKSTORE
WHERE 1=1
All values returned by Exp1 are equal in length even though Exp2 and Link are different in size.
So back to the problem, how can I run a query to replace the left-side with the correct server if I can't separate them out?
OK this is tricky, I did some Foxpro 20 years ago but don't have it to hand.
Your SELECT statement looks OK to me. In the comments under the question Thomas G created this DbFiddle which shows that in a 'normal' dbms, your SELECT statement gives the result you are expecting: https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=37047d2b7efb91aaa029fa0fb98eea24
So the problem must be something FoxPro/dBase specific rather than a problem with your SELECT statement.
Reading up I see people say that with FoxPro always use ALLTRIM() when using RIGHT() or LEN() on table fields because the data gets returned padded with spaces. I don't see how that would cause the exact bug you're seeing but you could try this maybe:
SELECT RIGHT(ALLTRIM(LINK),LEN(ALLTRIM(LINK))-8) ,LEN(ALLTRIM(LINK))-8,RIGHT(ALLTRIM(LINK),77),ALLTRIM(LINK)
FROM LINKSTORE
WHERE DOCLBL = "V46145002A"
edit: OK I got a better idea - are there other rows in your result set?
According to this: https://www.tek-tips.com/viewthread.cfm?qid=1706948 ... when you do SELECT (expr) in FoxPro whatever the length of the expr in the first row becomes that max length for that 'field' and so all subsequent rows get truncated to that length. Makes sense in a crazy 1970s sort of way.
So perhaps you have a row of data above the one we are talking about which comes out at 68 chars long and so every subsequent value gets truncated to that length.
The way around it is to pad your expression results with CAST or PADR:
SELECT PADR(RIGHT(ALLTRIM(LINK),LEN(ALLTRIM(LINK))-8),100),LEN(ALLTRIM(LINK))-8,PADR(RIGHT(ALLTRIM(LINK),77),100),LINK
FROM LINKSTORE
WHERE DOCLBL = "V46145002A"
Or same without the ALLTRIM()
SELECT PADR(RIGHT(LINK,LEN(LINK)-8),100),LEN(LINK)-8,PADR(RIGHT(LINK,77),100),LINK
FROM LINKSTORE
WHERE DOCLBL = "V46145002A"
I am using a tool to produce SQL queries and I need to filter one of the queries with a multiple parameters.
The query is similar to this:
Select *
From Products
Where (#ProductTypeIds is null or Product.ProductTypeId in (#ProductTypeIds))
I know the above query is not correct on a traditional SQL, read on..
Essentially, I'm trying to apply a filter where if nothing is passed for #ProductTypeIds parameter, the where condition is not applied.
When multiple parameters are being passed, though, #ProductTypeIds is being translated by the tool into the following query:
Select *
From Products
Where (#ProductTypeIds1, #ProductTypeIds2 is null or Product.ProductTypeId in (#ProductTypeIds1, #ProductTypeIds2))
Which is clearly an invalid query. So I thought I could be clever and use COALESCE to check if they are null:
Select *
From Products
Where (COALESCE(#ProductTypeIds, null) is null or Product.ProductTypeId in (#ProductTypeIds))
This query is being translated correctly, however, now my use of COALESCE throws an error:
At least one of the arguments to COALESCE must be an expression that is not the NULL constant.
How can I efficiently check that #ProductTypeIds (which be being translated into #ProductTypeIds1, #ProductTypeIds2 is all null so I can apply the filter or ignore?
In other words, is there a way to Distinct a list of parameters to check if the final result is null ?
Thanks
I have no idea how your tool works, but try the following.
Instead of checking for null check for the value that will never come in your params like:
WHERE COALESCE(#ProductTypeIds1, #ProductTypeIds2, -666) == -666 OR ...
I have a query where it is subtracting from two columns and then dividing to generate a percentage complete. If the area hasn't been started it propduces NULL I would like it to instead show 00 or 0.
Here is my Query:
substr(count(process_locations.count_attempt_id)/count(processes.process_id),2,2) as "Percentage Complete"
I have try NVL, and COALESE, but am unsure where to place them I have tried a few combinations, but i Receive errors.
I have also tried a CASE WHEN ELSE END, but it still said null.
You may try like this:-
NVL(substr(count(process_locations.count_attempt_id)/count(processes.process_id),2,2),0) as "Percentage Complete"
Well, an unpopulated "area" is null unless the field is specified as "not null." If you have permissions, you might want to do that. Otherwise use NVL to substitute any NULLS with zeros.
I am trying to do -
Where doctype is not null (doctype=documenttype)
I had a look at the SQL on MSDN for not null and where clauses and i cannot seem to find anything.
My last attempt was
where DocType is not null (f4111dt.DocType=f0911.documenttype)
But it is throwing up an error around f4111dt which is not an issue
If i just have where 4111dt.DocType=f0911dt.documenttype
then i lose the null values (which i want) which are in 4111dt.DocType because they do not match to anything in f0911dt.documenttype.
However if i dont have the statement 4111dt.DocType=f0911dt.documenttype
The document types wont match up...
In case you are trying to bring also those where doctype is null:
Where DocType is null OR (f4111dt.DocType=f0911.documenttype)
Try this
where DocType is not null AND (f4111dt.DocType=f0911.documenttype)
I have the following SQL:
Select dmvndn "Vendor Number", IFNULL(sum(dmsls) / sum(dmprc), 0) "Calculation"
From MyFile
Group By dmvndn
However, when i run this, i am still getting null records in my "Calculation" field.
I have also tried the COALESCE function, which returns the same results. I get some records as 0, and some records are blank (or, null).
Both fields are of type P, which i am told is packed numeric.
any ideas or suggestions?
Edit 1
It seems that the problem is not with either of these fields being NULL, it is that one or both fields are 0. And when i divide by zero, i get the empty / blank result.
Try
Sum(IFNULL(dmsls,0)) / Sum(IFNULL(dmprc,0))
A trick of this kind helps me in MS SQL Server:
Select
dmvndn "Vendor Number",
IFNULL(sum(dmsls) / NULLIF(sum(dmprc), 0), 0) "Calculation"
From MyFile
Group By dmvndn
I wonder if it can't help you in DB2.
UPDATE: an explanation.
Basically, it replaces the divisor with NULL if it's 0. And you may probably know that when at least one of the operands is NULL, the result of the operation becomes NULL as well.
To account for the result being NULL you already had your IFNULL on the result. It didn't make much difference then, because none of the operands was likely to be NULL. However, now using IFNULL makes perfect sense.