NOT operator in Advanced Pack Reports

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • alasdaircr
    Active Community Member
    • Aug 2014
    • 525

    NOT operator in Advanced Pack Reports

    Hello,

    Something that would be immensely useful would be the support of a NOT operator along side the current OR and AND specifiers in the report filter list.

    How do we go about getting this implemented?

  • alasdaircr
    Active Community Member
    • Aug 2014
    • 525

    #2
    E.g. I want to get a list of companies which DON'T have an active Opportunity of Type 'Partnership'. Easy enough with SQL, but how to handle this in your ORM?

    PHP Code:
    /* Count of Accounts */
    select count(*) FROM account a WHERE deleted = 0;
    
    /* Count of Active Partnership Opportunities */
    select count(*) FROM opportunity o LEFT JOIN account a On o.account_id=a.id AND a.deleted = 0 WHERE o.deleted = 0 AND o.type = 'Partnership' AND o.stage NOT IN ('Closed Won', 'Closed Lost');
    
    /* The query I want via a NOT operator */
    select count(*) from account a LEFT JOIN opportunity o ON o.deleted = 0 AND o.type = 'Partnership' AND o.stage NOT IN ('Closed Won', 'Closed Lost') AND a.id = o.account_id WHERE a.deleted = 0 AND o.account_id IS NULL; 
    

    Comment

    • yuri
      Member
      • Mar 2014
      • 8528

      #3
      If we added "Not In" filter for enum fields you would be able to apply De Morgan's law !(A AND B) = !A OR !B to achieve NOT operator. "NOT (statement)" is not supported by mysql.
      Last edited by yuri; 04-19-2017, 11:16 AM.
      If you find EspoCRM good, we would greatly appreciate if you could give the project a star on GitHub. We believe our work truly deserves more recognition. Thanks.

      Comment

      • alasdaircr
        Active Community Member
        • Aug 2014
        • 525

        #4
        Yes I wasn't meaning an actual SQL operator but a 'report filter' operator. Can't be done in SQL direct, but a query could be build up using joins.

        That way any subquery (anything underneath the NOT report filter operator) would be joined on a NULL which would open this up to more than just enums. It could be any query of any complexity. I wouldn't know where to start looking though, and it's a bit beyond my skills I think!

        Comment

        • alasdaircr
          Active Community Member
          • Aug 2014
          • 525

          #5
          Originally posted by yurikuzn
          If we added "Not In" filter for enum fields you would be able to apply De Morgan's law !(A AND B) = !A OR !B to achieve NOT operator. "NOT (statement)" is not supported by mysql.
          How would this translate to an SQL query? Just so I can check the numbers I'm getting.

          Comment

          • yuri
            Member
            • Mar 2014
            • 8528

            #6
            I thought about adding an ability to specify excluding report to exclude not needed records by another report. Your 3rd query is not just applying NOT operator. Not sure how we could even implement UI for such ones. For simple NOT operator we can resort to !(A && B) = !A || !B rule.
            If you find EspoCRM good, we would greatly appreciate if you could give the project a star on GitHub. We believe our work truly deserves more recognition. Thanks.

            Comment

            • alasdaircr
              Active Community Member
              • Aug 2014
              • 525

              #7
              I understand the excluding report bit but that's basically the same as the target list exclusion thing which isn't really generic enough.

              I think the UI is the simple bit, the tricky bit is turning it into a SQL query!

              I would suggest anything underneath a NOT filter operator is a sub query which is then joined against the other queries on the same 'node level' and which is joined on id IS NULL.
              Click image for larger version  Name:	Screen Shot 2017-04-19 at 13.01.33.png Views:	3 Size:	22.4 KB ID:	27698
              Attached Files

              Comment

              • alasdaircr
                Active Community Member
                • Aug 2014
                • 525

                #8
                Originally posted by yurikuzn
                Your 3rd query is not just applying NOT operator
                I'm not talking about the SQL NOT operator, I'm talking about an exclusion, you could call it whatever you want, but in boolean terms, NOT is the correct term right?

                Comment

                • yuri
                  Member
                  • Mar 2014
                  • 8528

                  #9
                  It would be tricky to implement. LEFT JOIN + IS NULL pair will be needed only for hasMany relationships. And we will need to group same relationships under a single JOIN ON'. For the rest of fields under NOT it should be a regular NOT w/o join.

                  If we treated NOT part as SQL where clause "id NOT IN (SUBREPORT_GENERATED_FROM_NOT_STATEMENT)" wouldn't this give the same result?
                  Last edited by yuri; 04-19-2017, 12:46 PM.
                  If you find EspoCRM good, we would greatly appreciate if you could give the project a star on GitHub. We believe our work truly deserves more recognition. Thanks.

                  Comment

                  • alasdaircr
                    Active Community Member
                    • Aug 2014
                    • 525

                    #10
                    Originally posted by yurikuzn
                    IIf we treated NOT part as SQL where clause "id NOT IN (SUBREPORT_GENERATED_FROM_NOT_STATEMENT)" wouldn't this give the same result?
                    You're right that seems like a better approach. Here is my updated query for the above NOT filter use.
                    PHP Code:
                    SELECT Count(*) 
                    FROM   account a 
                    WHERE  a.deleted = 0 
                           AND a.id NOT IN (SELECT a.id 
                                            FROM   account a 
                                                   JOIN opportunity o 
                                                     ON a.id = o.account_id 
                                            WHERE  o.deleted = 0 
                                                   AND o.type = 'Partnership' 
                                                   AND o.stage NOT IN ( 'Closed Won', 'Closed Lost')
                    ); 
                    
                    Last edited by alasdaircr; 04-19-2017, 01:09 PM.

                    Comment

                    • alasdaircr
                      Active Community Member
                      • Aug 2014
                      • 525

                      #11
                      (I don't mean to confuse things by using a NOT IN with the enum, that would also be a useful field filter option, but is not important to what we're talking about)

                      Comment

                      • yuri
                        Member
                        • Mar 2014
                        • 8528

                        #12
                        Is performance good? I tried such queries on different mysql servers and it was fast.
                        If you find EspoCRM good, we would greatly appreciate if you could give the project a star on GitHub. We believe our work truly deserves more recognition. Thanks.

                        Comment

                        • alasdaircr
                          Active Community Member
                          • Aug 2014
                          • 525

                          #13
                          It's very good but we don't have large data sets, just thousands of accounts, hundreds of opportunities.

                          Comment

                          • alasdaircr
                            Active Community Member
                            • Aug 2014
                            • 525

                            #14
                            I think MySQL optimises so it's a JOIN with a temporary table on account.id so it should be very fast

                            Comment

                            • yuri
                              Member
                              • Mar 2014
                              • 8528

                              #15
                              Yes. It does. It was slow in older version I believe.
                              If you find EspoCRM good, we would greatly appreciate if you could give the project a star on GitHub. We believe our work truly deserves more recognition. Thanks.

                              Comment

                              Working...