Appian version of below SQL query

Certified Senior Developer

How can I write below SQL query through query entity in Appian

Select * from A where A.colmn1 = max(A.colmn1)

  Discussion posts and replies are publicly visible

  • There are 2 primary options here:

    Option 1 (most scalable), create a view in the database which contains the query that matches your main CDT, but points to the view instead.  Then utilize a simple a!queryEntity() over the view CDT to always return the max row.  Best for overhead and scalability.  I also always recommend for views, changing the "SELECT *" into a list of all your columns specifically such as "SELECT id, userName, amount, date.." etc, as changes to the table structure will not automatically be reflected in your view and this can cause confusion for debugging without being able to see which columns are listed (the view would have to be re-published as-is, no changes, utilizing "*" if you change the underlying table structure later).

    Option 2 requires querying all values into Appian to utilize the max() function, then a second query to the data source to filter for the max value you are looking for.  If you are concerned with scalability (as we normally are) and your data set growing, this method will limit at 1 MB of data during the initial query, and slow down as it approaches that number.  For cases where, say, users enter 1 to 100 rows per request, and you want to find the max row of a specific request, this should be fine.  Essentially if the submissions are unlimited, you will want to steer to option 1 (I like Option 1 for all of these cases anyway).

    Option 2 Sample:

    a!localVariables(
      local!yourDataPoint: "id", /* change to your data point */
      local!max: tointeger(
        max(  
          property(
            a!queryEntity(
              entity: cons!COE_DS_SAMPLE, /* change to your data store */
              fetchTotalCount: false,
              query: a!query(
                paginginfo: a!pagingInfo(1,-1),
                selection: a!querySelection(
                  columns: {
                    a!queryColumn(
                      field: local!yourDataPoint
                    )
                  }
                )
              )
            ).data,
            local!yourDataPoint,
            0
          )
        )
      ),
      local!maxRow: a!queryEntity(
        entity: cons!COE_DS_SAMPLE, /* change to your data store */
        fetchTotalCount: false,
        query: a!query(
          paginginfo: a!pagingInfo(1,1),
          filter: a!queryFilter(
            field: local!yourDataPoint,
            operator: "=",
            value: local!max
          )
        )
      ).data,
      
      local!maxRow
    )

  • 0
    Certified Senior Developer
    in reply to Chris

    Thanks  for the elaborate response. For now we had to go with second approach. In fact, first approach is reasonable, I have recommended and asked them for that equivalent view to SQL query.

    But, max() doesn't work with dates. Any direct function to return max date, rather than sorting in descending order and then picking first item which I am doing right now?

  • +1
    Certified Lead Developer
    in reply to Chris

    TBH, this seems like a lot of running around / bending-over-backwards to do essentially this:

    a!localVariables(
      local!maxRow: a!queryEntity(
        entity: cons!COE_DS_SAMPLE,
        query: a!query(
          paginginfo: a!pagingInfo(
            startIndex: 1,
            batchSize: 1,
            sort: a!sortInfo(   /* this should get the max row by "colmn1" in almost all cases */
              field: "colmn1",
              ascending: false()
            )
          )
        )
      ).data,
    
      local!maxRow
    )

  • Sorting is a great option (including for dates).  I may have been rusty from the long weekend Slight smile

  • 0
    Certified Senior Developer
    in reply to Mike Schmitt

    That's what I am doing right now.  Haha Slight smile

  • 0
    Certified Lead Developer
    in reply to varunbawa
    That's what I am doing right now

    I think this is the best supported way of doing such a thing in Appian, at least when we assume the value you're sorting by will usually be unique (and/or you're only expecting a single row to be returned).

  • 0
    Certified Lead Developer
    in reply to Chris
    create a view in the database which contains the query that matches your main CDT, but points to the view instead. 

    BTW, if we're bringing bespoke Views into this, I hope you're aware (as I only learned several weeks ago now) that with the current DB version(s), we can now use Window Functions, including row_number() which is powerful.  Basically you can arbitrarily define partitions within a given query result and assign row numbers to the resulting rows, and then sort (and even select by) those row numbers.  This means that in your new view, you could create a row_number that applies against all rows in the table, sorting inverted by the target date column, then just query the result for "row 1".

  • Yep, ROW_NUMBER() is powerful!  With Appian our biggest use for it is typically assigning a unique ID to a data set that would not have one otherwise, such as aggregating data from multiple sources, statistics, etc etc.

    SELECT TOP (100) PERCENT ROW_NUMBER() OVER (ORDER BY requestStartTime DESC) AS Row, 
    step,requestByName FROM tblCOE_SAMPLE_TABLE

  • 0
    Certified Lead Developer
    in reply to Chris

    For me its biggest usefulness has been selecting a single result to join when sorted on an arbitrary parameter, which previously required super laborious and unintuitive workarounds to pull off (and even then, didn't always work very well).