Results 1 to 18 of 18

Thread: [RESOLVED] Equivalent of Nz() Function

  1. #1

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,638

    Resolved [RESOLVED] Equivalent of Nz() Function

    I have query that includes this in the SELECT statement (as one of many fields):
    Code:
    IIF(STRM_Survey.flgNoSurvey = 0,Nz((SELECT SUM(CountNew) FROM STRM_Redds WHERE STRM_Redds.SurveyID = STRM_Survey.SurveyID),0),Null)  AS NewRedds
    That works in Access, but not in ADO.NET, because Nz is not recognized in ADO.NET. In SQL Server, I would use IsNull rather than Nz, but IsNull is a recognized function in Access, and it doesn't do the same thing as it does in SQL Server.

    I realize that I could write this as an utterly ugly IIF within IIF, but it seems like I would have to write it like this:
    Code:
    IIF(STRM_Survey.flgNoSurvey = 0,IIF(ISNull(SELECT SUM(CountNew) FROM STRM_Redds WHERE STRM_Redds.SurveyID = STRM_Survey.SurveyID),0),SELECT SUM(CountNew) FROM STRM_Redds WHERE STRM_Redds.SurveyID = STRM_Survey.SurveyID)  AS NewRedds
    which seems like a massive waste of time, as it runs a sub-query twice. Therefore, I'm looking for a replacement for Nz that will work in ADO.NET. Is there such a thing?

    I do have an alternative, in this case, but it is probably worse than the double sub-query.
    Last edited by Shaggy Hiker; Dec 6th, 2024 at 04:17 PM.
    My usual boring signature: Nothing

  2. #2
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687

    Re: Equivalent of Nz() Function

    Would COALESCE work?

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  3. #3

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,638

    Re: Equivalent of Nz() Function

    Nope, Coalesce isn't a recognized function.

    What's annoying is that Nz is recognized in Access, but apparently not in OLEDB ADO.Net, while IsNull is used in the fashion that it works in Access, but not in the fashion it is used in SQL Server. Meanwhile, Coalesce isn't there at all.
    Last edited by Shaggy Hiker; Dec 5th, 2024 at 06:47 PM.
    My usual boring signature: Nothing

  4. #4
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,872

    Re: Equivalent of Nz() Function

    Eliminate the Nz...

    Code:
    IIF(STRM_Survey.flgNoSurvey = 0,
      (SELECT SUM(
                         IIF(CountNew IS NULL, 0, CountNew)
                        ) 
       FROM STRM_Redds WHERE STRM_Redds.SurveyID = STRM_Survey.SurveyID)
    ,Null)  AS NewRedds
    That way, the most inner IIF (3rd line) will never return a NULL, meaning the SUM will always return at least a 0
    Last edited by Zvoni; Dec 6th, 2024 at 08:34 AM.
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  5. #5

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,638

    Re: Equivalent of Nz() Function

    Yeah, that was it. It sure helps if you can type.

    At first, it wasn't working, but it was because I wrote IFF rather than IIF. All that did was give a syntax error without anything more helpful, such as noting an unrecognized function. It took a while to track that down.
    Last edited by Shaggy Hiker; Dec 6th, 2024 at 12:13 PM.
    My usual boring signature: Nothing

  6. #6

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,638

    Re: Equivalent of Nz() Function

    I guess I need to unresolve this.

    The query runs, it just doesn't work, which kind of has me baffled. What Zvoni wrote, runs without issue (though it did reveal that the first IIF is actually wrong, but that's an internal process issue), but Nulls are still Null.

    The theory is sound: SUM the result of the IIF, which will either produce 0, or some other integer, so the SUM of those integers should always be an integer. But in practice, if there is a Null in that inner IIF, the result of the SUM is still Null.

    Since I've utterly botched copy and pastes before, here's the actual line that is still returning Null when CountNew is Null:

    Code:
     IIF(STRM_Survey.flgNoSurvey = 0, (SELECT SUM(IIf (CountNew IS NULL, 0, CountNew)) FROM STRM_Redds WHERE STRM_Redds.SurveyID = STRM_Survey.SurveyID),Null) AS NewRedds,
    My usual boring signature: Nothing

  7. #7
    New Member
    Join Date
    Dec 2024
    Posts
    12

    Re: Equivalent of Nz() Function

    Instead of nested IIFs, try using COALESCE() - it returns the first non-null value. Or handle the null check in your C# code. Either should work in ADO.NET.

  8. #8
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687

    Re: Equivalent of Nz() Function

    Quote Originally Posted by grindmore View Post
    Instead of nested IIFs, try using COALESCE() - it returns the first non-null value. Or handle the null check in your C# code. Either should work in ADO.NET.
    That's what I thought...

    but...
    Quote Originally Posted by Shaggy Hiker View Post
    Nope, Coalesce isn't a recognized function.

    What's annoying is that Nz is recognized in Access, but apparently not in OLEDB ADO.Net, while IsNull is used in the fashion that it works in Access, but not in the fashion it is used in SQL Server. Meanwhile, Coalesce isn't there at all.
    Which I don't get because it shoul;d be a SQL function...
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  9. #9
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,872

    Re: Equivalent of Nz() Function

    Quote Originally Posted by techgnome View Post
    That's what I thought...

    but...

    Which I don't get because it shoul;d be a SQL function...
    but not in Access.
    REPLACE is another which Access only knows from „inside“ Access
    has driven me barmy in the past
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  10. #10

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,638

    Re: Equivalent of Nz() Function

    Yeah, it's doing that. That inner IIF SHOULD work.
    I tried a variant on that, which looked like this:

    IIf (CountNew IS NULL,0, 2)

    Since CountNew is almost always going to be 1, this should have essentially doubled CountNew, which is what happened, but I still got Nulls where CountNew was Null. It appears that the Access SQL engine has decided, "it's Null, I don't care what you do with it, the result is Null." It feels like a shortcut. Stop processing on Nulls, or something like that.
    My usual boring signature: Nothing

  11. #11
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,872

    Re: Equivalent of Nz() Function

    What about a default value of 0 for CountNew?

    EDIT: i did try out above most inner Iif in Access, sooooo: are those „real“ NULLs?
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  12. #12

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,638

    Re: Equivalent of Nz() Function

    No, actually they are not...sort of, and that might offer up a different solution. The CountNew field is non-nullable, and often is 0. However, the record may not exist. CountNew is in a child table left outer joined to a parent for the sake of this query. The bulk of the fields in the query come from the parent, with a sum of CountNew from the child. There may be no children, though, so when CountNew is Null, it's because there are no children to sum up. Is there a different approach that would work in that case?


    There will be no children if flgNoSurvey is True and there MIGHT be no children if flgNoSurvey is false. If flgNoSurvey is True, then we want Null in that field. If flgNoSurvey is false, but there STILL are no children, then we want 0.
    Last edited by Shaggy Hiker; Dec 8th, 2024 at 10:51 AM.
    My usual boring signature: Nothing

  13. #13
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,872

    Re: Equivalent of Nz() Function

    Replace the inner Iif with „0+CountNew“?
    just brainstorming here….

    EDIT: Forget it. SomeThing plus NULL still returns NULL
    Last edited by Zvoni; Dec 9th, 2024 at 01:59 AM.
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  14. #14
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,872

    Re: Equivalent of Nz() Function

    btw: If everything fails, and you don't want to "fork" your Client-Code (Checking if the backend is Access or MSSQL),
    an alternative might be to store the specific SQL-Statement within the Database itself in a Simpletext-Column in a separate Table.

    From your client, you just pull that Statement from the Backend, assign it as the "real" statement, and off you go (setting Parameters not withstanding)
    (It's my "Go-To"-Technique if i have to support different SQL-Syntaxes)

    In your case, in Access you would store the Query with the NZ-Function, in MSSQL the "version" with COALESCE (or whatever function you use) in its respective Table.
    From the client, the SQL to pull it out is the same for both backends:
    SELECT Statement FROM tbl_SQL_Statements WHERE StatementID=3
    (and StatementID is a basically a constant, which value must be the same in both backends, so a Primary Key but not AutoInc)
    Last edited by Zvoni; Dec 9th, 2024 at 02:30 AM.
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  15. #15
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,872

    Re: Equivalent of Nz() Function

    AHA!
    Had the same phenomenon like you, and your "LEFT JOIN" was the hint i was searching for

    This works in Access:
    Code:
    SELECT T1.SomeTextField, T1.SomeIntField, IIF(T2.CN IS NULL, 0, T2.CN) AS CN2 FROM table1 AS T1
    LEFT JOIN (
    SELECT FK, SUM(CountNew) AS CN FROM table2 GROUP BY FK) AS T2 
    ON T1.ID=T2.FK
    FK in T2 is the Foreign Key to PK in T1.

    Since you said, that CountNew is NON NULL, the second/inner SELECT within the LEFT JOIN will never return a NULL for the SUM.
    Meaning: We have to catch the NULL AFTER LEFT JOIN-ing

    EDIT: That said, i think i have to rework my first attempt above to
    Code:
    IIF(STRM_Survey.flgNoSurvey = 0,
      (SELECT IIF(
                SUM(CountNew) IS NULL, 0, SUM(CountNew)
                        ) 
       FROM STRM_Redds WHERE STRM_Redds.SurveyID = STRM_Survey.SurveyID)
    ,Null)  AS NewRedds
    which looks "redundant", but apparanetly works at least in Access
    (I just tried it with your "version" of a LEFT JOIN)
    Last edited by Zvoni; Dec 9th, 2024 at 03:34 AM.
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  16. #16

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,638

    Re: [RESOLVED] Equivalent of Nz() Function

    That got it. Very interesting. I would not have thought of checking whether the Sum of CountNew Is Null. The more I think about it, the more I find it almost arbitrary.
    My usual boring signature: Nothing

  17. #17
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,872

    Re: [RESOLVED] Equivalent of Nz() Function

    Quote Originally Posted by Shaggy Hiker View Post
    The more I think about it, the more I find it almost arbitrary.
    Not really if you think about it.

    Remember: in a Query a Filter is applied first, THEN any functions on Fields.
    Meaning in your case: All records get filtered FIRST according to the inner WHERE-Clause, which you pass the outer ID to.

    Since you stated that CountNew is NON NULL, any records where you do have a match, WILL return an integer for CountNew
    The opposite is also true: where there is no match, you get NOTHING (as in: RecordCount=0), and NOTHING is not NULL.

    So there is NOTHING you could actually compare if it's NULL.
    That's why my first approach failed.
    I also expected CountNew itself to be NULL, which is wrong. It was NOTHING (as in: RecordCount=0)
    BUT: The SUM of NOTHING is NULL

    btw: It's also exactly the reason, why i don't like the "version" of your LEFT JOIN.
    I'd probably go with my "true" LEFT JOIN (see above). Then it's clear what happens where.

    Nevermind Performance-Reasons.
    For an unfathomable reason, i always think your inner SELECT gets executed as many times there are ID's "injected" from outside.
    So 1000 ID's from outside = inner SELECT gets executed 1000 times.

    But i might be completely wrong here (i never look at execution-plans, i always look on my clock)
    Last edited by Zvoni; Dec 10th, 2024 at 02:15 AM.
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  18. #18

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,638

    Re: [RESOLVED] Equivalent of Nz() Function

    Ah, I get it. I was thinking that the Nothing WAS the same as Null, but Nothing only resolves to Null. If I query for just the field, I get Nothing, but that is displayed as Null. The SUM() forced the Nothing to resolve for the sake of the operation.
    My usual boring signature: Nothing

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width