Search code examples
c#sqlms-access-2016

C# DataSet Designer - AccesDB - Combine two rows into one


I need your help with an SQL query, that I am trying to build in C# Dataset Query Builder...

SELECT HouseHold.HHID, Client.FIRST_NAME, Client.LAST_NAME 
FROM ((Client 
INNER JOIN HouseHold_Client ON Client.CID = HouseHold_Client.CID) 
INNER JOIN HouseHold ON HouseHold_Client.HHID = HouseHold.HHID)

Above code gives me the list of all HouseHolds (their ID) with Clients belonging to them:

HHID  |  FIRST_NAME |  LAST_NAME
------------------------------
1     |  Penelope   |  Grant
1     |  Brian      |  Dyer
2     |  James      |  Newman
2     |  Richard    |  Parsons

.. but I can't figure out how to get people belonging to same HouseHold to show up on the same line, like this for a Data Grid View later on:

HHID | I_FIRST_NAME | I_LAST_NAME | II_FIRST_NAME | II_LAST_NAME
-----------------------------------------------------------------
1    | Penelope     | Grant       | Brian         | Dyer
2    | James        | Newman      | Richard       | Parsons

I have found loads of very similar questions, but very few had the same exact problem to solve. The ones (one or two) that really had the same problem and it had a solution, I just couldn't twist around my problem.

Any help is very much appreciated... Thank you very much, AD


Solution

  • Since you have only 2 persons per household, you can use the trick to get the minimum and maximum client Id per household. This is done in a subquery.

    SELECT
        X.HHID,
        C1.FIRST_NAME AS I_FIRST_NAME, C1.LAST_NAME AS I_LAST_NAME,
        C2.FIRST_NAME AS II_FIRST_NAME, C2.LAST_NAME AS II_LAST_NAME
    FROM
        ((  SELECT
                HHID, Min(CID) AS MinCId, IIf(Max(CID)=Min(CID), Null, Max(CID))  AS MaxCId
            FROM HouseHold_Client
            GROUP BY HHID
        ) X
        INNER JOIN Client AS C1
            ON X.MinCId = C1.CID)
        LEFT JOIN Client AS C2
            ON X.MaxCId = C2.CID;
    

    The purpose of the IIf() expression is to output the maximum client Id only if it is different from the minimum client Id. To also return a record when MaxCId is Null, a LEFT JOIN is required on C2.

    I did not join the HouseHold table here, since we only need the HHID from it, which is also available in HouseHold_Client. You can of course join it as well, if you need other columns from it.


    Subquery:

    (  SELECT
            HHID, Min(CID) AS MinCId, IIf(Max(CID)=Min(CID), Null, Max(CID))  AS MaxCId
        FROM HouseHold_Client
        GROUP BY HHID
    ) X
    

    Subqueries must be enclosed in parentheses and be given a name (here X). X acts as a normal table having the columns HHID, MinCId and MaxCId in the main query. It is grouped by HHID. I.e., it returns one row per HHID. Min(CID) returns the smallest CID and Max(CID) largest CID per HHID.

    In the case where you have 2 clients per HHID, this means that Min and Max will yield these 2 clients. If you have only 1 client, then both Min and Max will return the same client. If this is the case, then the IIf will return Null instead of Max(CID) to avoid returning twice the same client.