0

I am trying to merge two separate queries that work into one query that would also work.

I have several tables and need some data from all of them.

I have a table of tasks (this is just the tasks themselves, some may have been completed).

Each tasks has one or more rewards for completing the task, so I also have a reward_categories table which contains all the possibly rewards, and a reward_task_categories table which contains which rewards are associated to which task.

I have another table which inner joins to the tasks table which contains a list of todo_tasks and who needs to complete them.

I have a table of characters some of these will be completing the todo_tasks.

So I need all the fields from then todo_tasks table, just the name of the task from the tasks table, the name of the character to complete the task from the characters table and finally the stumbling block one reward that the character would get from completing the task.

I'm basically trying to merge these two queries.

SELECT `tt`.`id`, `t`.`task_name` FROM `todo_tasks` `tt`
    INNER JOIN `tasks` `t` ON `tt`.`task_id` = `t`.`id`;
SELECT `category_id`, `category_name` FROM `reward_task_categories` `rtc`
    INNER JOIN `reward_categories` `rc` ON `rtc`.`category_id` = `rc`.`id`
    WHERE `task_id` = 1 ORDER BY `rtc`.`category_id` ASC LIMIT 1;

I have tried these queries with no success so far.

SELECT `tt`.`id`, `t`.`task_name`, `rc`.*, `tt`.`character_id`,
    `c`.`character_name`, `c`.`character_priority` FROM `todo_tasks` `tt`
    INNER JOIN `tasks` `t` ON `tt`.`task_id` = `t`.`id`
    INNER JOIN `characters` `c` ON `tt`.`character_id` = `c`.`id`
    INNER JOIN
        (
            SELECT * FROM `reward_task_categories` `rtci`
            INNER JOIN `reward_categories` `rc` ON `rtci`.`category_id` = `rc`.`id`
            WHERE `task_id` = `tt`.`task_id` ORDER BY `rtci`.`category_id` ASC
            LIMIT 1
        ) `rtc` ON `t`.`task_id` = `rtc`.`task_id`
    LIMIT 1;

If I take out the sub query the above works, albeit missing some data I need. As it is it gives me the error Unknown table 'rc' I guess this is from the INNER JOIN sub query.

Based on @Barmar comment from below I believe they are saying I need to do something like this, this query however still gives me the error of Unknown table 'rc'.

SELECT `tt`.`id`, `t`.`task_name`, `rc`.*, `tt`.`character_id`,
    `c`.`character_name`, `c`.`character_priority` FROM `todo_tasks` `tt`
    INNER JOIN `tasks` `t` ON `tt`.`task_id` = `t`.`id`
    INNER JOIN `characters` `c` ON `tt`.`character_id` = `c`.`id`
    INNER JOIN
        (
            SELECT * FROM `reward_task_categories` `rtci`
            INNER JOIN `reward_categories` `rc` ON `rtci`.`category_id` = `rc`.`id`
            WHERE `task_id` = `tt`.`task_id` GROUP BY `rtci`.`task_id`
            ORDER BY `rtci`.`category_id` ASC LIMIT 1
        ) `rtc` ON `t`.`task_id` = `rtc`.`task_id`
    LIMIT 1;

I've made some progress in that it now seems to work without any errors, the only thing is that when a task has multiple rewards it repeats the task x times for each reward, I only want it to return the first reward it finds based on the order by condition.

SELECT `tt`.`id`, `t`.`task_name`, `rtc`.`category_name`, `tt`.`character_id`,
    `c`.`character_name`, `c`.`character_priority` FROM `todo_tasks` `tt`
    INNER JOIN `tasks` `t` ON `tt`.`task_id` = `t`.`id`
    INNER JOIN `characters` `c` ON `tt`.`character_id` = `c`.`id`
    LEFT JOIN
        (
            SELECT * FROM `reward_task_categories` `rtci`
            INNER JOIN `reward_categories` `rc` ON `rtci`.`category_id` = `rc`.`id`
        ) `rtc` ON `tt`.`task_id` = `rtc`.`task_id`
    LIMIT 1;
AeroMaxx
  • 213
  • 2
  • 9
  • You have no `ON` condition in the last JOIN. How is the result of the subquery supposed to be related to the other tables? – Barmar Jul 27 '23 at 05:19
  • Why does the subquery only use `task_id = 1`? Shouldn't it return 1 row for every task, and then you join with `t.id`? – Barmar Jul 27 '23 at 05:20
  • @Barmar I fixed the `ON` part I think, not sure if that's correct but it would be how it links to the other tables. The `task_id = 1` was a typo that I inadvertently made when trying to combine the two query mentioned in the question, I have fixed that also. – AeroMaxx Jul 27 '23 at 06:59
  • Your subquery will still only return 1 row because of `LIMIT 1`. I suspect you want 1 row per task, not 1 total row. – Barmar Jul 27 '23 at 07:02
  • See https://stackoverflow.com/questions/33145885/sql-selecting-from-two-tables-with-inner-join-and-limit?noredirect=1&lq=1 – Barmar Jul 27 '23 at 07:02
  • @Barmar oh yes I know, I was just using the very last `LIMIT 1` is a test that I can just copy and paste into the SQL console, showing only 1 record is easier to see it's working than returning all records, the very last `LIMIT 1` would be removed once I know it's working. – AeroMaxx Jul 27 '23 at 07:13
  • But when you use that, the join won't work, because you'll only get the row that matches the first task ID. The subquery needs to be grouped by task ID. – Barmar Jul 27 '23 at 07:19
  • @Barmar Do you have an example of what you mean? What if I wanted a query result with all records, but also potentially in the future wanted to fetch a single record from the database/tables and have the same data returned. – AeroMaxx Jul 27 '23 at 07:26
  • I gave you a link above to examples. – Barmar Jul 27 '23 at 07:28
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/254688/discussion-between-barmar-and-aeromaxx). – Barmar Jul 27 '23 at 07:29

0 Answers0