I currently have a table which displays the inventory values of users. It works, but it displays all users and their inventory values in a random order. I’m wanting to limit the table to the top 5 descending inventory values only.
This data cuts across three tables: DB Fiddle
- Users
- Inventories (contains a row for each item a user has in their inventory)
- Items (contains the value of the items)
x
echo "<table>
<th>Inventory Value</th>
<th>Username</th>";
// Choose the users we want (verified users).
$refineUsers=$db->query("SELECT userID FROM users WHERE accountVerified = 'true'");
while($users=$db->fetch_row($refineUsers)) {
// Fetch the inventories of the users we want.
$fetchInventories=$db->query("SELECT * FROM inventories WHERE userID = '".$users['userID']."'");
$totalInventoryValue=0;
while($inventories=$db->fetch_row($fetchInventories)) {
// Fetch the values of the items.
$fetchItemsData=$db->query("SELECT value FROM items WHERE itemID = '".$inventories['itemID']."'");
while($items=$db->fetch_row($fetchItemsData)) {
// Calculate the values of the various items within the user's inventory.
$totalItemsValue=($items['value'] * $inventories['quantity']);
// Calculate the total value of the user's inventory.
$totalInventoryValue+=$totalItemsValue;
}
}
// Display the values of each user's inventory.
echo "<td>".money_format($totalInventoryValue)."</td>";
echo "<td>".username($users['userID'])."</td>";
echo "<tr>";
}
echo "</table>";
The output is something like:
Inventory Value | Username |
---|---|
120000 | Account1 |
112000 | Accounts2 |
70000 | Account3 |
169000 | Accounts5 |
I’m guessing this could be done with a JOIN query, but I’m not very experienced and haven’t done one that cuts across three tables before. I don’t know how I can use these nested queries to get the top 5 inventory totals and arrange them in descending order.
Advertisement
Answer
- Join the three table is accordance with the rules in your original nested queries.
- Group the data on username values.
- This will create AGGREGATE data which will need to be organized within the
SUM()
function so that the item quantities associate with the correct item value. - Now it is trivial to apply your ORDER BY and LIMIT rules.
SQL: (Demo)
SELECT username,
SUM(
IF(
inventoryItemID = itemID,
inventoryQuantity * itemValue,
0
)
) AS total
FROM users
JOIN inventory ON userID = inventoryUserID
JOIN items ON inventoryItemID = itemID
WHERE accountVerified = 'true'
GROUP BY username
ORDER BY total DESC
LIMIT 5