skip to Main Content

I am trying to display two specific persons (a couples income) in a table (by foreach loop PHP).
Each person should be shown in a column and the income per row.

To connect the couple/persons I have created a table "j_b_controller" which can join the couples together by a "joint_budget_id". The j_b_controller also have a "position_order" coloumn to control where to put the person1 and person2. Person1 have position_order = 1 and person2 = 2.

When one of the accounts log on I start this session
$_SESSION['budget_id'] = $jointbudget['joint_budget_id'];

An example:
The income table look like this

person1 have income1, income2, income 3 and income 5.
person2 have income1
The amount in income1 for each person is not the same.
Each income have its own specifik "row_type_id" so income1 have row_type_id 1.

Income table

The j_b_controller table looks like this

Person1 have joint_budget_id = 1 and position_order = 1
Person2 have joint_budget_id = 1 and position_order = 2

j_b_controller table

Everything should be displayed in a HTML table (PHP foreach loop)

ORDER BY row_type_id

Person 1 Person 2
Income1 Income1
Income2 Empty
Income3 Empty
Income5 Empty

Hopefully you can see the picture below
HTML Table

The two SQL queries that should be joined/unioned is

//Select incomes from person with position_order = 1
    $stmt = $pdo->prepare('SELECT i.id, i.name, i.amount AS p2_amount, i.row_type_id FROM incomes i JOIN j_b_controller jb ON i.account_id = jb.account_id AND jb.joint_budget_id = ? AND jb.position_order = **1** ORDER BY i.id AND i.row_type_id ASC');
    $stmt->execute([$_SESSION['budget_id']]);
    $income_rows_122s = $stmt->fetchAll(PDO::FETCH_ASSOC);

and

//Select incomes from person with position_order = 2
    $stmt = $pdo->prepare('SELECT i.id, i.name, i.amount AS p2_amount, i.row_type_id FROM incomes i JOIN j_b_controller jb ON i.account_id = jb.account_id AND jb.joint_budget_id = ? AND jb.position_order = **2** ORDER BY i.id AND i.row_type_id ASC');
    $stmt->execute([$_SESSION['budget_id']]);
    $income_rows_122s = $stmt->fetchAll(PDO::FETCH_ASSOC);

I have already tried to use UNION the two and I have tried to make a subquery

My subquery is the closed I got so far but with the subquery I can only return 1 row for person2.. and it is repeated as many times as Person1 have incomes.

$stmt = $pdo->prepare('SELECT i.*, i.amount AS p1_amount, (SELECT amount FROM incomes i JOIN j_b_controller jb ON i.account_id = jb.account_id AND jb.joint_budget_id = ? AND jb.position_order = 2 ORDER BY i.id AND i.row_type_id ASC) AS p2_amount FROM incomes i JOIN  j_b_controller jb ON i.account_id = jb.account_id AND jb.joint_budget_id = ? AND jb.position_order = 1 ORDER BY i.id AND i.row_type_id ASC');
    $stmt->execute([$_SESSION['budget_id'], $_SESSION['budget_id']]);
    $income_rows_1s = $stmt->fetchAll(PDO::FETCH_ASSOC);

My foreach looks like this

<tbody>
                <?php if (empty($income_rows_1s)) : ?>
                    <tr>
                        <td colspan="8" style="text-align:center;">There are no objects</td>
                    </tr>
                <?php else : ?>
                    <?php foreach ($income_rows_1s as $income_rows_1) : ?>
                       
                        <?php if (empty($income_rows_1['row_type_id'])) :?>


                        <?php else : ?>
                            <tr role="row" class="item" data-modal=".incomeInfo<?= md5($income_rows_1['row_type_id']) ?>">
                                <td role="gridcell" class="table-edit-link"></td>
                                <td role="gridcell" class="table-view-link"><a href="#"><?= $income_rows_1['name'] ?></a></td>
                                <?php if (empty($income_rows_1['p1_amount']) or ($income_rows_1['p1_amount']) == 0.00) :  ?>
                                    <td role="gridcell"></td>
                                <?php else : ?>
                                <td role="gridcell"><?= number_format($income_rows_1['p1_amount'], $decimals, ',', '.'); ?></td>
                                <?php endif; ?>
                                <?php if (empty($income_rows_1['row_type_id']) or (empty($income_rows_1['p2_amount']) or ($income_rows_1['p2_amount']) == 0.00)) : ?>
                                    <td role="gridcell"></td>
                                 <?php else : ?>
                                <td role="gridcell"><?= number_format($income_rows_1['p2_amount'], $decimals, ',', '.'); ?></td>
                                <?php endif; ?>
                                <td role="gridcell"><?= number_format(($income_rows_1['p1_amount'] + $income_rows_1['p2_amount']), $decimals, ',', '.') ?></td>
                                <td role="gridcell"><?= number_format(($income_rows_1['p1_amount'] + $income_rows_1['p2_amount']) * 12, $decimals, ',', '.') ?></td>
                            </tr>
                        <?php endif; ?>
                    <?php endforeach; ?>
                <?php endif; ?>
            </tbody>

The result looks like this (picture)
HTML Table

Person2 should only have income1 shown 1 time and the rest is empty. If person2 had income 6 then the income6 row for person1 would be empty and then person2 had the income6 amount in the table.

Hopefully this make sence. I am NOT a skilled/educated programmer but I like to program a bit in my spare time.

2

Answers


  1. If i understand you right, youre searching for something like this?

    SELECT i.amount AS p1_amount, ii.amount AS p2_amount FROM incomes i 
    JOIN j_b_controller jb ON i.account_id = jb.account_id AND jb.joint_budget_id = ? AND jb.position_order = **1** 
    LEFT JOIN incomes ii ON ii.account_id = jb.account_id AND jb.joint_budget_id = ? AND jb.position_order = **2** 
    ORDER BY i.id AND i.row_type_id ASC, ii.id AND ii.row_type_id ASC;
    
    Login or Signup to reply.
  2. This will give you your desired result set in one query:

    SELECT
        IFNULL(i.name, 'Total') AS Name,
        SUM(IF(jb.position_order = 1, i.amount, NULL)) AS "Person 1",
        SUM(IF(jb.position_order = 2, i.amount, NULL)) AS "Person 2"
    FROM incomes i
    INNER JOIN j_b_controller jb ON i.account_id = jb.account_id
    WHERE jb.joint_budget_id = 1
    GROUP BY i.name WITH ROLLUP
    ORDER BY ISNULL(i.name), i.name
    

    result:

    +---------+----------+----------+
    | Name    | Person 1 | Person 2 |
    +---------+----------+----------+
    | Income1 | 14000.99 |  5200.99 |
    | Income2 |  1900.99 |     NULL |
    | Income3 |  3269.99 |     NULL |
    | Income5 |   130.99 |     NULL |
    | Total   | 19302.96 |  5200.99 |
    +---------+----------+----------+
    

    In your PHP code, you can check for NULL values when iterating your table.

    I’m not quite sure how row_type_id is supposed to work – what happens when Person 1 has a different value for row_type_id than Person 2?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search