Question

This is my table [Property]:

Loanno  Balance amount  PropertyType
1001045 308731.770000     1
1001045 2007700.740000    2
1001045 3087318905.770    3
1001045 308731.770000     4
1001046 306589.67         1
1001046 456321.23         1
1001046 6932542.89        1
1001047 582563.56         1
1001047 965421.34         2
1001048 567894.34         1
1001048 567894.34         2

I have to get the property type for a [Loanno] having highest balance amount. If there is a tie in the highest balance amount and if the Property type for the loannumber is different then for that Loan number I have to populate property type as '8'. So my final Output should look like this:

Loanno  PropertyType
1001045     3
1001046     1
1001047     2
1001048     8

Edit

This is what I tried, but I am getting duplicate records.

SELECT DISTINCT 
    LT.LOANNO, 
    IIF(COUNTS.MAX_BALANCE > 1, 8,LT.PROPERTY_TYPE) AS PROPERTY_TYPE1 
FROM 
    PROPERTY LT 
    INNER JOIN
    ( 
        SELECT 
            DISTINCT_ROWS.LOANNO, 
            COUNT(DISTINCT_ROWS.MaxBalance) AS MAX_BALANCE 
        FROM
            (
                SELECT DISTINCT 
                    L.LOANNO, 
                    MaxBalance 
                FROM 
                    PROPERTY AS L 
                    INNER JOIN 
                    (
                        SELECT 
                            LOANNO, 
                            MAX(BALANCE_AMOUNT) AS MaxBalance 
                        FROM PROPERTY 
                        GROUP BY LOANNO
                    ) AS SUB 
                        ON (L.LOANNO=SUB.LOANNO) 
                            AND (L.BALANCE_AMOUNT=SUB.MaxBalance)
            ) AS DISTINCT_ROWS
        GROUP BY DISTINCT_ROWS.LOANNO 
    ) AS COUNTS
        ON LT.LOANNO=COUNTS.LOANNO 
GROUP BY LT.LOANNO, IIF(COUNTS.MAX_BALANCE > 1, 8, LT.PROPERTY_TYPE)
Was it helpful?

Solution 2

Here's how I built up the query:

Step 1: Create a query to find the maximum balance for each [Loanno] and save that query as [Loanno_MaxBalance]:

SELECT 
    Loanno, 
    MAX([Balance amount]) AS MaxBalance 
FROM [Property] 
GROUP BY Loanno

Step 2a: Create a query to count the number of rows that have the maximum balance, using our saved query above to keep things simple:

SELECT 
    [Property].Loanno, 
    [Property].[Balance amount], 
    COUNT(*) AS RowCount 
FROM 
    [Property]
    INNER JOIN
    [Loanno_MaxBalance]
        ON Loanno_MaxBalance.Loanno=[Property].Loanno 
            AND Loanno_MaxBalance.MaxBalance=[Property].[Balance amount]
GROUP BY [Property].Loanno, [Property].[Balance amount]

Step 2b: That doesn't look too scary, so let's incorporate the SQL from Step 1 as a subquery:

SELECT 
    [Property].Loanno, 
    [Property].[Balance amount], 
    COUNT(*) AS RowCount 
FROM 
    [Property]
    INNER JOIN
    (
        SELECT 
            Loanno, 
            MAX([Balance amount]) AS MaxBalance 
        FROM [Property] 
        GROUP BY Loanno
    ) AS Loanno_MaxBalance
        ON Loanno_MaxBalance.Loanno=[Property].Loanno 
            AND Loanno_MaxBalance.MaxBalance=[Property].[Balance amount]
GROUP BY [Property].Loanno, [Property].[Balance amount]

So now this query stands on its own, and we don't need to keep [Loanno_MaxBalance] as a separate saved query in Access.

We'll save the above query as [Loanno_MaxBalance_Count].

Step 3a: Now to derive the [PropertyType] values using the [Property] table and the [Loanno_MaxBalance_Count] query:

SELECT DISTINCT 
    [Property].Loanno, 
    IIf(Loanno_MaxBalance_Count.RowCount>1, 8, [Property].PropertyType) AS PropertyType
FROM 
    [Property]
    INNER JOIN 
    [Loanno_MaxBalance_Count] 
        ON [Property].Loanno=Loanno_MaxBalance_Count.Loanno 
            AND [Property].[Balance amount]=Loanno_MaxBalance_Count.[Balance amount]

Step 3b: Gee, that's not too bad at all. Let's "go for it" and replace the [Loanno_MaxBalance_Count] query reference with its SQL code (from Step 2b) as a subquery:

SELECT DISTINCT 
    [Property].Loanno, 
    IIf(Loanno_MaxBalance_Count.RowCount>1, 8, [Property].PropertyType) AS PropertyType
FROM 
    [Property]
    INNER JOIN 
    (
        SELECT 
            [Property].Loanno, 
            [Property].[Balance amount], 
            COUNT(*) AS RowCount 
        FROM 
            [Property]
            INNER JOIN
            (
                SELECT 
                    Loanno, 
                    MAX([Balance amount]) AS MaxBalance 
                FROM [Property] 
                GROUP BY Loanno
            ) AS Loanno_MaxBalance
                ON Loanno_MaxBalance.Loanno=[Property].Loanno 
                    AND Loanno_MaxBalance.MaxBalance=[Property].[Balance amount]
        GROUP BY [Property].Loanno, [Property].[Balance amount]
    ) AS Loanno_MaxBalance_Count
        ON [Property].Loanno=Loanno_MaxBalance_Count.Loanno 
            AND [Property].[Balance amount]=Loanno_MaxBalance_Count.[Balance amount]

That's it! One self-contained query with no need for saved Access query dependencies.

OTHER TIPS

Your query requirements are challenging for Access SQL. A custom VBA function would allow you to use a simpler SELECT statement, but brings issues which may be unacceptable for you:

  1. A UDF (user-defined function) can only be used in a query run within an Access session ... not when you use other code (.Net, Java, PHP, VBScript, etc) to connect to the db and run your query.
  2. UDFs can be slow.

If you can use a UDF, this query using the GetPropertyType function (see below) returns what you asked for. Note I used tblProperties as the table name because Property is a reserved word. Also I assumed Long for the data type of Loanno, Currency for Balance_amount, and Long for Property_Type.

SELECT
    sub.Loanno,
    GetPropertyType(sub.Loanno,sub.MaxBalance) AS PropertyType
FROM
    (
        SELECT
            Loanno,
            Max(Balance_amount) AS MaxBalance
        FROM tblProperties
        GROUP BY Loanno
    ) AS sub
ORDER BY sub.Loanno;

This is the function, which I tested with Access 2007.

Public Function GetPropertyType(ByVal pLoanno As Long, _
        ByVal pBalance_amount As Currency) As Long

    Const cstrQdf As String = "qryLoanPropertyTypesCount"
    Dim db As DAO.database
    Dim qdf As DAO.QueryDef
    Dim lngReturn As Long

    Set db = CurrentDb
    Set qdf = db.QueryDefs(cstrQdf)
    qdf.Parameters("which_Loanno") = pLoanno
    qdf.Parameters("which_Balance_amount") = pBalance_amount

    If qdf.OpenRecordset()(0) > 1 Then
        lngReturn = 8
    Else
        lngReturn = DLookup("Property_Type", "tblProperties", _
            "Loanno=" & pLoanno & " AND Balance_amount=" & _
            pBalance_amount)
    End If

    Set qdf = Nothing
    Set db = Nothing
    GetPropertyType = lngReturn
End Function

The function uses this saved parameter query, qryLoanPropertyTypesCount:

PARAMETERS which_Loanno Long, which_Balance_amount Currency;
SELECT Count(*) AS num_PropertyTypes
FROM
    (
        SELECT DISTINCT
            p.Loanno,
            p.Balance_amount,
            p.Property_Type
        FROM tblProperties AS p
        WHERE
                p.Loanno = [which_Loanno]
            AND p.Balance_amount = [which_Balance_amount]
    ) AS sub;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top