Getting a derived attribute through two different tables





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







1















I need to get the salary of an employee through two different tables: his gains and his discounts. The relation from the table employee to the two tables is a many to many relation. So I need to take the employee_id, get all the gain_id in the employee_gains table, add all of them and subtract with the analogue result in the discounts.



I tried this creating a view for the salary:



  CREATE VIEW salary as 
select ((select sum(value) from gains
where gain_id in (select gain_id from gain_employee where employee_id=2))
-
(select sum(value) from discount
where discount_id in (select gain_id from discount_employee where employee_id=2)));


However, this only (and successfully) gives me the salary for the employee with ID 2. But how can I make this generic? I want a view salary for all the employees.










share|improve this question































    1















    I need to get the salary of an employee through two different tables: his gains and his discounts. The relation from the table employee to the two tables is a many to many relation. So I need to take the employee_id, get all the gain_id in the employee_gains table, add all of them and subtract with the analogue result in the discounts.



    I tried this creating a view for the salary:



      CREATE VIEW salary as 
    select ((select sum(value) from gains
    where gain_id in (select gain_id from gain_employee where employee_id=2))
    -
    (select sum(value) from discount
    where discount_id in (select gain_id from discount_employee where employee_id=2)));


    However, this only (and successfully) gives me the salary for the employee with ID 2. But how can I make this generic? I want a view salary for all the employees.










    share|improve this question



























      1












      1








      1








      I need to get the salary of an employee through two different tables: his gains and his discounts. The relation from the table employee to the two tables is a many to many relation. So I need to take the employee_id, get all the gain_id in the employee_gains table, add all of them and subtract with the analogue result in the discounts.



      I tried this creating a view for the salary:



        CREATE VIEW salary as 
      select ((select sum(value) from gains
      where gain_id in (select gain_id from gain_employee where employee_id=2))
      -
      (select sum(value) from discount
      where discount_id in (select gain_id from discount_employee where employee_id=2)));


      However, this only (and successfully) gives me the salary for the employee with ID 2. But how can I make this generic? I want a view salary for all the employees.










      share|improve this question
















      I need to get the salary of an employee through two different tables: his gains and his discounts. The relation from the table employee to the two tables is a many to many relation. So I need to take the employee_id, get all the gain_id in the employee_gains table, add all of them and subtract with the analogue result in the discounts.



      I tried this creating a view for the salary:



        CREATE VIEW salary as 
      select ((select sum(value) from gains
      where gain_id in (select gain_id from gain_employee where employee_id=2))
      -
      (select sum(value) from discount
      where discount_id in (select gain_id from discount_employee where employee_id=2)));


      However, this only (and successfully) gives me the salary for the employee with ID 2. But how can I make this generic? I want a view salary for all the employees.







      database postgresql






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 16 '18 at 18:54









      Mahesh H Viraktamath

      4071523




      4071523










      asked Nov 16 '18 at 15:43









      Marcos MartinMarcos Martin

      277




      277
























          2 Answers
          2






          active

          oldest

          votes


















          0














          I would suggest you to use two CTEs to calculate the gains and discounts and then do a FULL OUTER JOIN on the two sets. This will ensure that you get proper values such as 0 for missing gains or discounts for an employee_id. If you want to ignore them such cases just change it to a plain INNER JOIN



          CREATE OR REPLACE VIEW V_salary AS  --give proper name to indicate it's a view 
          WITH ge
          AS (SELECT e.employee_id,
          SUM(g.value) AS gain_value
          FROM gain_employee e
          JOIN gains g --use left join if some employees don't
          --have an entry in gains
          ON e.gain_id = g.gain_id
          GROUP BY e.employee_id),
          de
          AS (SELECT e.employee_id,
          SUM(d.value) AS dis_value
          FROM discount_employee e
          JOIN discounts d --use left join if some employees don't
          --have an entry in discount
          ON e.discount_id = d.discount_id
          GROUP BY e.employee_id)
          SELECT COALESCE(ge.employee_id, gd.employee_id), --gets you atleast one of
          --them when one may be missing.
          COALESCE(ge.gain_value, 0) - COALESCE(de.dis_value, 0) AS salary
          FROM ge
          FULL OUTER JOIN de -- to consider case where one of them is absent
          ON ge.employee_id = de.employee_id;





          share|improve this answer































            0














            This should do it -



            CREATE VIEW salary as
            select S1.employee_id, (S1.gains - S2.discounts) as salary
            from (select ge.employee_id, sum(g.value) as gains
            from gain_employee ge, gains g
            where ge.gain_id = g.gain_id
            group by ge.employee_id) S1,
            (select de.employee_id, sum(d.value) as discounts
            from discount_employee de, discounts d
            where de.doscount_id = d.discount_id
            group by de.employee_id) S2
            where S1.employee_id = S2.employee_id;


            Then you can query this view with employee_id as the condition.






            share|improve this answer


























              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53341116%2fgetting-a-derived-attribute-through-two-different-tables%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              0














              I would suggest you to use two CTEs to calculate the gains and discounts and then do a FULL OUTER JOIN on the two sets. This will ensure that you get proper values such as 0 for missing gains or discounts for an employee_id. If you want to ignore them such cases just change it to a plain INNER JOIN



              CREATE OR REPLACE VIEW V_salary AS  --give proper name to indicate it's a view 
              WITH ge
              AS (SELECT e.employee_id,
              SUM(g.value) AS gain_value
              FROM gain_employee e
              JOIN gains g --use left join if some employees don't
              --have an entry in gains
              ON e.gain_id = g.gain_id
              GROUP BY e.employee_id),
              de
              AS (SELECT e.employee_id,
              SUM(d.value) AS dis_value
              FROM discount_employee e
              JOIN discounts d --use left join if some employees don't
              --have an entry in discount
              ON e.discount_id = d.discount_id
              GROUP BY e.employee_id)
              SELECT COALESCE(ge.employee_id, gd.employee_id), --gets you atleast one of
              --them when one may be missing.
              COALESCE(ge.gain_value, 0) - COALESCE(de.dis_value, 0) AS salary
              FROM ge
              FULL OUTER JOIN de -- to consider case where one of them is absent
              ON ge.employee_id = de.employee_id;





              share|improve this answer




























                0














                I would suggest you to use two CTEs to calculate the gains and discounts and then do a FULL OUTER JOIN on the two sets. This will ensure that you get proper values such as 0 for missing gains or discounts for an employee_id. If you want to ignore them such cases just change it to a plain INNER JOIN



                CREATE OR REPLACE VIEW V_salary AS  --give proper name to indicate it's a view 
                WITH ge
                AS (SELECT e.employee_id,
                SUM(g.value) AS gain_value
                FROM gain_employee e
                JOIN gains g --use left join if some employees don't
                --have an entry in gains
                ON e.gain_id = g.gain_id
                GROUP BY e.employee_id),
                de
                AS (SELECT e.employee_id,
                SUM(d.value) AS dis_value
                FROM discount_employee e
                JOIN discounts d --use left join if some employees don't
                --have an entry in discount
                ON e.discount_id = d.discount_id
                GROUP BY e.employee_id)
                SELECT COALESCE(ge.employee_id, gd.employee_id), --gets you atleast one of
                --them when one may be missing.
                COALESCE(ge.gain_value, 0) - COALESCE(de.dis_value, 0) AS salary
                FROM ge
                FULL OUTER JOIN de -- to consider case where one of them is absent
                ON ge.employee_id = de.employee_id;





                share|improve this answer


























                  0












                  0








                  0







                  I would suggest you to use two CTEs to calculate the gains and discounts and then do a FULL OUTER JOIN on the two sets. This will ensure that you get proper values such as 0 for missing gains or discounts for an employee_id. If you want to ignore them such cases just change it to a plain INNER JOIN



                  CREATE OR REPLACE VIEW V_salary AS  --give proper name to indicate it's a view 
                  WITH ge
                  AS (SELECT e.employee_id,
                  SUM(g.value) AS gain_value
                  FROM gain_employee e
                  JOIN gains g --use left join if some employees don't
                  --have an entry in gains
                  ON e.gain_id = g.gain_id
                  GROUP BY e.employee_id),
                  de
                  AS (SELECT e.employee_id,
                  SUM(d.value) AS dis_value
                  FROM discount_employee e
                  JOIN discounts d --use left join if some employees don't
                  --have an entry in discount
                  ON e.discount_id = d.discount_id
                  GROUP BY e.employee_id)
                  SELECT COALESCE(ge.employee_id, gd.employee_id), --gets you atleast one of
                  --them when one may be missing.
                  COALESCE(ge.gain_value, 0) - COALESCE(de.dis_value, 0) AS salary
                  FROM ge
                  FULL OUTER JOIN de -- to consider case where one of them is absent
                  ON ge.employee_id = de.employee_id;





                  share|improve this answer













                  I would suggest you to use two CTEs to calculate the gains and discounts and then do a FULL OUTER JOIN on the two sets. This will ensure that you get proper values such as 0 for missing gains or discounts for an employee_id. If you want to ignore them such cases just change it to a plain INNER JOIN



                  CREATE OR REPLACE VIEW V_salary AS  --give proper name to indicate it's a view 
                  WITH ge
                  AS (SELECT e.employee_id,
                  SUM(g.value) AS gain_value
                  FROM gain_employee e
                  JOIN gains g --use left join if some employees don't
                  --have an entry in gains
                  ON e.gain_id = g.gain_id
                  GROUP BY e.employee_id),
                  de
                  AS (SELECT e.employee_id,
                  SUM(d.value) AS dis_value
                  FROM discount_employee e
                  JOIN discounts d --use left join if some employees don't
                  --have an entry in discount
                  ON e.discount_id = d.discount_id
                  GROUP BY e.employee_id)
                  SELECT COALESCE(ge.employee_id, gd.employee_id), --gets you atleast one of
                  --them when one may be missing.
                  COALESCE(ge.gain_value, 0) - COALESCE(de.dis_value, 0) AS salary
                  FROM ge
                  FULL OUTER JOIN de -- to consider case where one of them is absent
                  ON ge.employee_id = de.employee_id;






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 17 '18 at 6:37









                  Kaushik NayakKaushik Nayak

                  21.8k41332




                  21.8k41332

























                      0














                      This should do it -



                      CREATE VIEW salary as
                      select S1.employee_id, (S1.gains - S2.discounts) as salary
                      from (select ge.employee_id, sum(g.value) as gains
                      from gain_employee ge, gains g
                      where ge.gain_id = g.gain_id
                      group by ge.employee_id) S1,
                      (select de.employee_id, sum(d.value) as discounts
                      from discount_employee de, discounts d
                      where de.doscount_id = d.discount_id
                      group by de.employee_id) S2
                      where S1.employee_id = S2.employee_id;


                      Then you can query this view with employee_id as the condition.






                      share|improve this answer






























                        0














                        This should do it -



                        CREATE VIEW salary as
                        select S1.employee_id, (S1.gains - S2.discounts) as salary
                        from (select ge.employee_id, sum(g.value) as gains
                        from gain_employee ge, gains g
                        where ge.gain_id = g.gain_id
                        group by ge.employee_id) S1,
                        (select de.employee_id, sum(d.value) as discounts
                        from discount_employee de, discounts d
                        where de.doscount_id = d.discount_id
                        group by de.employee_id) S2
                        where S1.employee_id = S2.employee_id;


                        Then you can query this view with employee_id as the condition.






                        share|improve this answer




























                          0












                          0








                          0







                          This should do it -



                          CREATE VIEW salary as
                          select S1.employee_id, (S1.gains - S2.discounts) as salary
                          from (select ge.employee_id, sum(g.value) as gains
                          from gain_employee ge, gains g
                          where ge.gain_id = g.gain_id
                          group by ge.employee_id) S1,
                          (select de.employee_id, sum(d.value) as discounts
                          from discount_employee de, discounts d
                          where de.doscount_id = d.discount_id
                          group by de.employee_id) S2
                          where S1.employee_id = S2.employee_id;


                          Then you can query this view with employee_id as the condition.






                          share|improve this answer















                          This should do it -



                          CREATE VIEW salary as
                          select S1.employee_id, (S1.gains - S2.discounts) as salary
                          from (select ge.employee_id, sum(g.value) as gains
                          from gain_employee ge, gains g
                          where ge.gain_id = g.gain_id
                          group by ge.employee_id) S1,
                          (select de.employee_id, sum(d.value) as discounts
                          from discount_employee de, discounts d
                          where de.doscount_id = d.discount_id
                          group by de.employee_id) S2
                          where S1.employee_id = S2.employee_id;


                          Then you can query this view with employee_id as the condition.







                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Nov 16 '18 at 18:37

























                          answered Nov 16 '18 at 18:32









                          Mahesh H ViraktamathMahesh H Viraktamath

                          4071523




                          4071523






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53341116%2fgetting-a-derived-attribute-through-two-different-tables%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              List item for chat from Array inside array React Native

                              Thiostrepton

                              Caerphilly