showing columns in a particular pattern in postgresql












0















i have written a query which returns a table showing monthly total working hours of each person in the company. so the result is:



name*****jan************feb**********march ......... dec
Tom 170:24:31 186:27:09 140:00:00........158:17:56


i need a query which gives the following output:



name***jan***jan_salary****feb***feb_salary***....***dec***dec_salary      


the salary of each month is the total working hours of that month multiplied by 150$. how can i do this?
below is the query i have written to compute total working hours of each person for each month:



with hours as (
select "Staff_Id",
"Date",
case
when row_number() over w % 2 = 0 then
TO_CHAR("Time" - lag("Time") over w,'HH24:MI:SS')
end as hours
from "Org"."Clock"
window w as (partition by "Staff_Id", "Date" order by "Time")
), hours_per_month as (
select "Staff_Id",
extract(year from "Date")::int as work_year,
extract(month from "Date")::int as work_month,
sum(hours::interval) work_hours
from hours
where hours is not null
group by "Staff_Id", work_year, work_month
)
select "Staff_Id",
work_year,
sum("work_hours") filter (where work_month = 1) as jan,
sum("work_hours") filter (where work_month = 2) as feb,
sum("work_hours") filter (where work_month = 3) as march,
sum("work_hours") filter (where work_month = 4) as april,
sum("work_hours") filter (where work_month = 5) as may,
sum("work_hours") filter (where work_month = 6) as june,
sum("work_hours") filter (where work_month = 7) as july,
sum("work_hours") filter (where work_month = 8) as aug,
sum("work_hours") filter (where work_month = 9) as sep,
sum("work_hours") filter (where work_month = 10) as oct,
sum("work_hours") filter (where work_month = 11) as nov,
sum("work_hours") filter (where work_month = 12) as dec
from hours_per_month
group by "Staff_Id", work_year









share|improve this question





























    0















    i have written a query which returns a table showing monthly total working hours of each person in the company. so the result is:



    name*****jan************feb**********march ......... dec
    Tom 170:24:31 186:27:09 140:00:00........158:17:56


    i need a query which gives the following output:



    name***jan***jan_salary****feb***feb_salary***....***dec***dec_salary      


    the salary of each month is the total working hours of that month multiplied by 150$. how can i do this?
    below is the query i have written to compute total working hours of each person for each month:



    with hours as (
    select "Staff_Id",
    "Date",
    case
    when row_number() over w % 2 = 0 then
    TO_CHAR("Time" - lag("Time") over w,'HH24:MI:SS')
    end as hours
    from "Org"."Clock"
    window w as (partition by "Staff_Id", "Date" order by "Time")
    ), hours_per_month as (
    select "Staff_Id",
    extract(year from "Date")::int as work_year,
    extract(month from "Date")::int as work_month,
    sum(hours::interval) work_hours
    from hours
    where hours is not null
    group by "Staff_Id", work_year, work_month
    )
    select "Staff_Id",
    work_year,
    sum("work_hours") filter (where work_month = 1) as jan,
    sum("work_hours") filter (where work_month = 2) as feb,
    sum("work_hours") filter (where work_month = 3) as march,
    sum("work_hours") filter (where work_month = 4) as april,
    sum("work_hours") filter (where work_month = 5) as may,
    sum("work_hours") filter (where work_month = 6) as june,
    sum("work_hours") filter (where work_month = 7) as july,
    sum("work_hours") filter (where work_month = 8) as aug,
    sum("work_hours") filter (where work_month = 9) as sep,
    sum("work_hours") filter (where work_month = 10) as oct,
    sum("work_hours") filter (where work_month = 11) as nov,
    sum("work_hours") filter (where work_month = 12) as dec
    from hours_per_month
    group by "Staff_Id", work_year









    share|improve this question



























      0












      0








      0








      i have written a query which returns a table showing monthly total working hours of each person in the company. so the result is:



      name*****jan************feb**********march ......... dec
      Tom 170:24:31 186:27:09 140:00:00........158:17:56


      i need a query which gives the following output:



      name***jan***jan_salary****feb***feb_salary***....***dec***dec_salary      


      the salary of each month is the total working hours of that month multiplied by 150$. how can i do this?
      below is the query i have written to compute total working hours of each person for each month:



      with hours as (
      select "Staff_Id",
      "Date",
      case
      when row_number() over w % 2 = 0 then
      TO_CHAR("Time" - lag("Time") over w,'HH24:MI:SS')
      end as hours
      from "Org"."Clock"
      window w as (partition by "Staff_Id", "Date" order by "Time")
      ), hours_per_month as (
      select "Staff_Id",
      extract(year from "Date")::int as work_year,
      extract(month from "Date")::int as work_month,
      sum(hours::interval) work_hours
      from hours
      where hours is not null
      group by "Staff_Id", work_year, work_month
      )
      select "Staff_Id",
      work_year,
      sum("work_hours") filter (where work_month = 1) as jan,
      sum("work_hours") filter (where work_month = 2) as feb,
      sum("work_hours") filter (where work_month = 3) as march,
      sum("work_hours") filter (where work_month = 4) as april,
      sum("work_hours") filter (where work_month = 5) as may,
      sum("work_hours") filter (where work_month = 6) as june,
      sum("work_hours") filter (where work_month = 7) as july,
      sum("work_hours") filter (where work_month = 8) as aug,
      sum("work_hours") filter (where work_month = 9) as sep,
      sum("work_hours") filter (where work_month = 10) as oct,
      sum("work_hours") filter (where work_month = 11) as nov,
      sum("work_hours") filter (where work_month = 12) as dec
      from hours_per_month
      group by "Staff_Id", work_year









      share|improve this question
















      i have written a query which returns a table showing monthly total working hours of each person in the company. so the result is:



      name*****jan************feb**********march ......... dec
      Tom 170:24:31 186:27:09 140:00:00........158:17:56


      i need a query which gives the following output:



      name***jan***jan_salary****feb***feb_salary***....***dec***dec_salary      


      the salary of each month is the total working hours of that month multiplied by 150$. how can i do this?
      below is the query i have written to compute total working hours of each person for each month:



      with hours as (
      select "Staff_Id",
      "Date",
      case
      when row_number() over w % 2 = 0 then
      TO_CHAR("Time" - lag("Time") over w,'HH24:MI:SS')
      end as hours
      from "Org"."Clock"
      window w as (partition by "Staff_Id", "Date" order by "Time")
      ), hours_per_month as (
      select "Staff_Id",
      extract(year from "Date")::int as work_year,
      extract(month from "Date")::int as work_month,
      sum(hours::interval) work_hours
      from hours
      where hours is not null
      group by "Staff_Id", work_year, work_month
      )
      select "Staff_Id",
      work_year,
      sum("work_hours") filter (where work_month = 1) as jan,
      sum("work_hours") filter (where work_month = 2) as feb,
      sum("work_hours") filter (where work_month = 3) as march,
      sum("work_hours") filter (where work_month = 4) as april,
      sum("work_hours") filter (where work_month = 5) as may,
      sum("work_hours") filter (where work_month = 6) as june,
      sum("work_hours") filter (where work_month = 7) as july,
      sum("work_hours") filter (where work_month = 8) as aug,
      sum("work_hours") filter (where work_month = 9) as sep,
      sum("work_hours") filter (where work_month = 10) as oct,
      sum("work_hours") filter (where work_month = 11) as nov,
      sum("work_hours") filter (where work_month = 12) as dec
      from hours_per_month
      group by "Staff_Id", work_year






      sql postgresql case crosstab






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 19 at 19:34









      a_horse_with_no_name

      296k46451546




      296k46451546










      asked Jan 19 at 18:16









      RezaReza

      268




      268
























          1 Answer
          1






          active

          oldest

          votes


















          1














          I would think you can just add the salary into your "hours_per_month" subquery as follows:



          select "Staff_Id", 
          extract(year from "Date")::int as work_year,
          extract(month from "Date")::int as work_month,
          sum(hours::interval) work_hours,
          trunc (extract (epoch from sum(hours::interval)) / 3600) * 150 as salary
          from hours
          where hours is not null
          group by "Staff_Id", work_year, work_month


          This presupposes that you want to pay whole hours (15.8 hours = 15 hours of pay), but if not, that's easy enough to tweak.



          extract (hours might work also, but not if the number of total hours is > 24. In my opinion, it's not worth it to assume it will, even in a case like this where it would be unrealistic to assume a human would work in excess of 24 hours at one time. Also, you could unwittingly later clone this code to work for something like "machine hours," in which case it would be very possible.



          Then, in your main query:



          select "Staff_Id", 
          work_year,
          sum("work_hours") filter (where work_month = 1) as jan,
          sum(salary) filter (where work_month = 1) as jan_salary,
          sum("work_hours") filter (where work_month = 2) as feb,
          sum(salary) filter (where work_month = 2) as feb_salary,
          ...
          sum("work_hours") filter (where work_month = 12) as dec,
          sum(salary) filter (where work_month = 12) as dec_salary
          from hours_per_month
          group by "Staff_Id", work_year


          Totally off-topic, and I'm not trying to tell you how to live your life, but when I see quotes around field and table names, unelss it's at the very last step of the query (rendering output) it makes my skin crawl. It also introduces so many chances for errors. As it happens, I'm not alone in my opinion:



          https://wiki.postgresql.org/wiki/Don%27t_Do_This#Don.27t_use_upper_case_table_or_column_names






          share|improve this answer
























          • great! but how can i do it using cross tab instead of filter? also for computing total working hours of each person in each month?

            – Reza
            Jan 20 at 5:56











          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%2f54270019%2fshowing-columns-in-a-particular-pattern-in-postgresql%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          I would think you can just add the salary into your "hours_per_month" subquery as follows:



          select "Staff_Id", 
          extract(year from "Date")::int as work_year,
          extract(month from "Date")::int as work_month,
          sum(hours::interval) work_hours,
          trunc (extract (epoch from sum(hours::interval)) / 3600) * 150 as salary
          from hours
          where hours is not null
          group by "Staff_Id", work_year, work_month


          This presupposes that you want to pay whole hours (15.8 hours = 15 hours of pay), but if not, that's easy enough to tweak.



          extract (hours might work also, but not if the number of total hours is > 24. In my opinion, it's not worth it to assume it will, even in a case like this where it would be unrealistic to assume a human would work in excess of 24 hours at one time. Also, you could unwittingly later clone this code to work for something like "machine hours," in which case it would be very possible.



          Then, in your main query:



          select "Staff_Id", 
          work_year,
          sum("work_hours") filter (where work_month = 1) as jan,
          sum(salary) filter (where work_month = 1) as jan_salary,
          sum("work_hours") filter (where work_month = 2) as feb,
          sum(salary) filter (where work_month = 2) as feb_salary,
          ...
          sum("work_hours") filter (where work_month = 12) as dec,
          sum(salary) filter (where work_month = 12) as dec_salary
          from hours_per_month
          group by "Staff_Id", work_year


          Totally off-topic, and I'm not trying to tell you how to live your life, but when I see quotes around field and table names, unelss it's at the very last step of the query (rendering output) it makes my skin crawl. It also introduces so many chances for errors. As it happens, I'm not alone in my opinion:



          https://wiki.postgresql.org/wiki/Don%27t_Do_This#Don.27t_use_upper_case_table_or_column_names






          share|improve this answer
























          • great! but how can i do it using cross tab instead of filter? also for computing total working hours of each person in each month?

            – Reza
            Jan 20 at 5:56
















          1














          I would think you can just add the salary into your "hours_per_month" subquery as follows:



          select "Staff_Id", 
          extract(year from "Date")::int as work_year,
          extract(month from "Date")::int as work_month,
          sum(hours::interval) work_hours,
          trunc (extract (epoch from sum(hours::interval)) / 3600) * 150 as salary
          from hours
          where hours is not null
          group by "Staff_Id", work_year, work_month


          This presupposes that you want to pay whole hours (15.8 hours = 15 hours of pay), but if not, that's easy enough to tweak.



          extract (hours might work also, but not if the number of total hours is > 24. In my opinion, it's not worth it to assume it will, even in a case like this where it would be unrealistic to assume a human would work in excess of 24 hours at one time. Also, you could unwittingly later clone this code to work for something like "machine hours," in which case it would be very possible.



          Then, in your main query:



          select "Staff_Id", 
          work_year,
          sum("work_hours") filter (where work_month = 1) as jan,
          sum(salary) filter (where work_month = 1) as jan_salary,
          sum("work_hours") filter (where work_month = 2) as feb,
          sum(salary) filter (where work_month = 2) as feb_salary,
          ...
          sum("work_hours") filter (where work_month = 12) as dec,
          sum(salary) filter (where work_month = 12) as dec_salary
          from hours_per_month
          group by "Staff_Id", work_year


          Totally off-topic, and I'm not trying to tell you how to live your life, but when I see quotes around field and table names, unelss it's at the very last step of the query (rendering output) it makes my skin crawl. It also introduces so many chances for errors. As it happens, I'm not alone in my opinion:



          https://wiki.postgresql.org/wiki/Don%27t_Do_This#Don.27t_use_upper_case_table_or_column_names






          share|improve this answer
























          • great! but how can i do it using cross tab instead of filter? also for computing total working hours of each person in each month?

            – Reza
            Jan 20 at 5:56














          1












          1








          1







          I would think you can just add the salary into your "hours_per_month" subquery as follows:



          select "Staff_Id", 
          extract(year from "Date")::int as work_year,
          extract(month from "Date")::int as work_month,
          sum(hours::interval) work_hours,
          trunc (extract (epoch from sum(hours::interval)) / 3600) * 150 as salary
          from hours
          where hours is not null
          group by "Staff_Id", work_year, work_month


          This presupposes that you want to pay whole hours (15.8 hours = 15 hours of pay), but if not, that's easy enough to tweak.



          extract (hours might work also, but not if the number of total hours is > 24. In my opinion, it's not worth it to assume it will, even in a case like this where it would be unrealistic to assume a human would work in excess of 24 hours at one time. Also, you could unwittingly later clone this code to work for something like "machine hours," in which case it would be very possible.



          Then, in your main query:



          select "Staff_Id", 
          work_year,
          sum("work_hours") filter (where work_month = 1) as jan,
          sum(salary) filter (where work_month = 1) as jan_salary,
          sum("work_hours") filter (where work_month = 2) as feb,
          sum(salary) filter (where work_month = 2) as feb_salary,
          ...
          sum("work_hours") filter (where work_month = 12) as dec,
          sum(salary) filter (where work_month = 12) as dec_salary
          from hours_per_month
          group by "Staff_Id", work_year


          Totally off-topic, and I'm not trying to tell you how to live your life, but when I see quotes around field and table names, unelss it's at the very last step of the query (rendering output) it makes my skin crawl. It also introduces so many chances for errors. As it happens, I'm not alone in my opinion:



          https://wiki.postgresql.org/wiki/Don%27t_Do_This#Don.27t_use_upper_case_table_or_column_names






          share|improve this answer













          I would think you can just add the salary into your "hours_per_month" subquery as follows:



          select "Staff_Id", 
          extract(year from "Date")::int as work_year,
          extract(month from "Date")::int as work_month,
          sum(hours::interval) work_hours,
          trunc (extract (epoch from sum(hours::interval)) / 3600) * 150 as salary
          from hours
          where hours is not null
          group by "Staff_Id", work_year, work_month


          This presupposes that you want to pay whole hours (15.8 hours = 15 hours of pay), but if not, that's easy enough to tweak.



          extract (hours might work also, but not if the number of total hours is > 24. In my opinion, it's not worth it to assume it will, even in a case like this where it would be unrealistic to assume a human would work in excess of 24 hours at one time. Also, you could unwittingly later clone this code to work for something like "machine hours," in which case it would be very possible.



          Then, in your main query:



          select "Staff_Id", 
          work_year,
          sum("work_hours") filter (where work_month = 1) as jan,
          sum(salary) filter (where work_month = 1) as jan_salary,
          sum("work_hours") filter (where work_month = 2) as feb,
          sum(salary) filter (where work_month = 2) as feb_salary,
          ...
          sum("work_hours") filter (where work_month = 12) as dec,
          sum(salary) filter (where work_month = 12) as dec_salary
          from hours_per_month
          group by "Staff_Id", work_year


          Totally off-topic, and I'm not trying to tell you how to live your life, but when I see quotes around field and table names, unelss it's at the very last step of the query (rendering output) it makes my skin crawl. It also introduces so many chances for errors. As it happens, I'm not alone in my opinion:



          https://wiki.postgresql.org/wiki/Don%27t_Do_This#Don.27t_use_upper_case_table_or_column_names







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jan 19 at 22:33









          HamboneHambone

          9,91552848




          9,91552848













          • great! but how can i do it using cross tab instead of filter? also for computing total working hours of each person in each month?

            – Reza
            Jan 20 at 5:56



















          • great! but how can i do it using cross tab instead of filter? also for computing total working hours of each person in each month?

            – Reza
            Jan 20 at 5:56

















          great! but how can i do it using cross tab instead of filter? also for computing total working hours of each person in each month?

          – Reza
          Jan 20 at 5:56





          great! but how can i do it using cross tab instead of filter? also for computing total working hours of each person in each month?

          – Reza
          Jan 20 at 5:56


















          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%2f54270019%2fshowing-columns-in-a-particular-pattern-in-postgresql%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

          Liquibase includeAll doesn't find base path

          How to use setInterval in EJS file?

          Petrus Granier-Deferre