Merging dummy/placeholder data into a SQL queryHow can I prevent SQL injection in PHP?How do I perform an IF…THEN in an SQL SELECT?Add a column with a default value to an existing table in SQL ServerHow to return only the Date from a SQL Server DateTime datatypeHow to check if a column exists in a SQL Server table?How to concatenate text from multiple rows into a single text string in SQL server?Parameterize an SQL IN clauseInserting multiple rows in a single SQL query?How do I UPDATE from a SELECT in SQL Server?Finding duplicate values in a SQL table

How would Japanese people react to someone refusing to say “itadakimasu” for religious reasons?

How can I prevent a user from copying files on another hard drive?

I'm yearning in grey

Can you place a web spell on a surface you cannot see?

How did space travel spread throughout the Star Wars galaxy?

What kind of chart is this?

Fibonacci sequence and other metallic sequences emerged in the form of fractions

How do I become a better writer when I hate reading?

Who was the youngest Executive Producer?

Boundaries and Buddhism

...and then she held the gun

Basic power tool set for Home repair and simple projects

How "fast" do astronomical events occur?

What is the context for Napoleon's quote "[the Austrians] did not know the value of five minutes"?

Is it possible to use just one shared folder for log shipping?

How to sort human readable size

I have found ports on my Samsung smart tv running a display service. What can I do with it?

Fill the maze with a wall-following Snake until it gets stuck

Bash function: Execute $@ command with each argument in sequence executed separately

How to make a villain when your PCs are villains?

Is this broken pipe the reason my freezer is not working? Can it be fixed?

Credit card validation in C

What is this plant I saw for sale at a Romanian farmer's market?

Why was New Asgard established at this place?



Merging dummy/placeholder data into a SQL query


How can I prevent SQL injection in PHP?How do I perform an IF…THEN in an SQL SELECT?Add a column with a default value to an existing table in SQL ServerHow to return only the Date from a SQL Server DateTime datatypeHow to check if a column exists in a SQL Server table?How to concatenate text from multiple rows into a single text string in SQL server?Parameterize an SQL IN clauseInserting multiple rows in a single SQL query?How do I UPDATE from a SELECT in SQL Server?Finding duplicate values in a SQL table






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








1















In our SQL Server 2016 database we have a Payments table which records monthly payments made by our customers, but as they do not necessarily pay every month we may have missing month data.



I now need to insert the missing monthly payment data (i.e a zero payment) for each customer for an SSRS report because the business wants to see every month on the report to assess customer payment frequency.



So in the SQL statement below, I first create a table variable and insert a row for each month and a zero payment amount. Then I've created some sample payment data with customer Id, month paid and the amount. What I then need to do is end up with a result that has 12 entries for each customer, one for each month, showing either the payment made that month or 0.



-- Dummy monthly payment data to use for missing months
DECLARE @DummyPayments TABLE
(
MonthNumber INT,
Payment MONEY
)

INSERT INTO @DummyPayments
select 1,0 union
select 2,0 union
select 3,0 union
select 4,0 union
select 5,0 union
select 6,0 union
select 7,0 union
select 8,0 union
select 9,0 union
select 10,0 union
select 11,0 union
select 12,0

-- This (much simplified) data would come from our Payments table
DECLARE @CustomerPayments TABLE
(
CustomerID INT,
MonthNumber INT,
Payment MONEY
)

-- Example customer 1 made payment in months 1,3,6,9
insert into @CustomerPayments values(1,1,100);
insert into @CustomerPayments values(1,3,120);
insert into @CustomerPayments values(1,6,140);
insert into @CustomerPayments values(1,9,95);

-- Example customer 2 made payment in months 2,5,10,12
insert into @CustomerPayments values(2,2,80);
insert into @CustomerPayments values(2,5,90);
insert into @CustomerPayments values(2,10,130);
insert into @CustomerPayments values(2,12,105);

-- Now I want to join real payments with dummy/missing payments
-- to get payment data for each month in the year.
with cust as
(
select distinct CustomerID
from @CustomerPayments
)
select * from @CustomerPayments cp
union
select c.CustomerID,
(select dp.MonthNumber
from @DummyPayments dp
where dp.MonthNumber not in (select cp.MonthNumber from @CustomerPayments cp where cp.CustomerID = c.CustomerID)),
0
from cust c


When I run it I get an error




Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.




I thought doing this with a union would work and I understand the error is telling me I'm getting too many results in each sub-query but short of using a cursor I can't work out how to do this. Perhaps I'm over complicating it but if anyone can help me out I'd appreciate it.










share|improve this question






























    1















    In our SQL Server 2016 database we have a Payments table which records monthly payments made by our customers, but as they do not necessarily pay every month we may have missing month data.



    I now need to insert the missing monthly payment data (i.e a zero payment) for each customer for an SSRS report because the business wants to see every month on the report to assess customer payment frequency.



    So in the SQL statement below, I first create a table variable and insert a row for each month and a zero payment amount. Then I've created some sample payment data with customer Id, month paid and the amount. What I then need to do is end up with a result that has 12 entries for each customer, one for each month, showing either the payment made that month or 0.



    -- Dummy monthly payment data to use for missing months
    DECLARE @DummyPayments TABLE
    (
    MonthNumber INT,
    Payment MONEY
    )

    INSERT INTO @DummyPayments
    select 1,0 union
    select 2,0 union
    select 3,0 union
    select 4,0 union
    select 5,0 union
    select 6,0 union
    select 7,0 union
    select 8,0 union
    select 9,0 union
    select 10,0 union
    select 11,0 union
    select 12,0

    -- This (much simplified) data would come from our Payments table
    DECLARE @CustomerPayments TABLE
    (
    CustomerID INT,
    MonthNumber INT,
    Payment MONEY
    )

    -- Example customer 1 made payment in months 1,3,6,9
    insert into @CustomerPayments values(1,1,100);
    insert into @CustomerPayments values(1,3,120);
    insert into @CustomerPayments values(1,6,140);
    insert into @CustomerPayments values(1,9,95);

    -- Example customer 2 made payment in months 2,5,10,12
    insert into @CustomerPayments values(2,2,80);
    insert into @CustomerPayments values(2,5,90);
    insert into @CustomerPayments values(2,10,130);
    insert into @CustomerPayments values(2,12,105);

    -- Now I want to join real payments with dummy/missing payments
    -- to get payment data for each month in the year.
    with cust as
    (
    select distinct CustomerID
    from @CustomerPayments
    )
    select * from @CustomerPayments cp
    union
    select c.CustomerID,
    (select dp.MonthNumber
    from @DummyPayments dp
    where dp.MonthNumber not in (select cp.MonthNumber from @CustomerPayments cp where cp.CustomerID = c.CustomerID)),
    0
    from cust c


    When I run it I get an error




    Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.




    I thought doing this with a union would work and I understand the error is telling me I'm getting too many results in each sub-query but short of using a cursor I can't work out how to do this. Perhaps I'm over complicating it but if anyone can help me out I'd appreciate it.










    share|improve this question


























      1












      1








      1


      0






      In our SQL Server 2016 database we have a Payments table which records monthly payments made by our customers, but as they do not necessarily pay every month we may have missing month data.



      I now need to insert the missing monthly payment data (i.e a zero payment) for each customer for an SSRS report because the business wants to see every month on the report to assess customer payment frequency.



      So in the SQL statement below, I first create a table variable and insert a row for each month and a zero payment amount. Then I've created some sample payment data with customer Id, month paid and the amount. What I then need to do is end up with a result that has 12 entries for each customer, one for each month, showing either the payment made that month or 0.



      -- Dummy monthly payment data to use for missing months
      DECLARE @DummyPayments TABLE
      (
      MonthNumber INT,
      Payment MONEY
      )

      INSERT INTO @DummyPayments
      select 1,0 union
      select 2,0 union
      select 3,0 union
      select 4,0 union
      select 5,0 union
      select 6,0 union
      select 7,0 union
      select 8,0 union
      select 9,0 union
      select 10,0 union
      select 11,0 union
      select 12,0

      -- This (much simplified) data would come from our Payments table
      DECLARE @CustomerPayments TABLE
      (
      CustomerID INT,
      MonthNumber INT,
      Payment MONEY
      )

      -- Example customer 1 made payment in months 1,3,6,9
      insert into @CustomerPayments values(1,1,100);
      insert into @CustomerPayments values(1,3,120);
      insert into @CustomerPayments values(1,6,140);
      insert into @CustomerPayments values(1,9,95);

      -- Example customer 2 made payment in months 2,5,10,12
      insert into @CustomerPayments values(2,2,80);
      insert into @CustomerPayments values(2,5,90);
      insert into @CustomerPayments values(2,10,130);
      insert into @CustomerPayments values(2,12,105);

      -- Now I want to join real payments with dummy/missing payments
      -- to get payment data for each month in the year.
      with cust as
      (
      select distinct CustomerID
      from @CustomerPayments
      )
      select * from @CustomerPayments cp
      union
      select c.CustomerID,
      (select dp.MonthNumber
      from @DummyPayments dp
      where dp.MonthNumber not in (select cp.MonthNumber from @CustomerPayments cp where cp.CustomerID = c.CustomerID)),
      0
      from cust c


      When I run it I get an error




      Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.




      I thought doing this with a union would work and I understand the error is telling me I'm getting too many results in each sub-query but short of using a cursor I can't work out how to do this. Perhaps I'm over complicating it but if anyone can help me out I'd appreciate it.










      share|improve this question
















      In our SQL Server 2016 database we have a Payments table which records monthly payments made by our customers, but as they do not necessarily pay every month we may have missing month data.



      I now need to insert the missing monthly payment data (i.e a zero payment) for each customer for an SSRS report because the business wants to see every month on the report to assess customer payment frequency.



      So in the SQL statement below, I first create a table variable and insert a row for each month and a zero payment amount. Then I've created some sample payment data with customer Id, month paid and the amount. What I then need to do is end up with a result that has 12 entries for each customer, one for each month, showing either the payment made that month or 0.



      -- Dummy monthly payment data to use for missing months
      DECLARE @DummyPayments TABLE
      (
      MonthNumber INT,
      Payment MONEY
      )

      INSERT INTO @DummyPayments
      select 1,0 union
      select 2,0 union
      select 3,0 union
      select 4,0 union
      select 5,0 union
      select 6,0 union
      select 7,0 union
      select 8,0 union
      select 9,0 union
      select 10,0 union
      select 11,0 union
      select 12,0

      -- This (much simplified) data would come from our Payments table
      DECLARE @CustomerPayments TABLE
      (
      CustomerID INT,
      MonthNumber INT,
      Payment MONEY
      )

      -- Example customer 1 made payment in months 1,3,6,9
      insert into @CustomerPayments values(1,1,100);
      insert into @CustomerPayments values(1,3,120);
      insert into @CustomerPayments values(1,6,140);
      insert into @CustomerPayments values(1,9,95);

      -- Example customer 2 made payment in months 2,5,10,12
      insert into @CustomerPayments values(2,2,80);
      insert into @CustomerPayments values(2,5,90);
      insert into @CustomerPayments values(2,10,130);
      insert into @CustomerPayments values(2,12,105);

      -- Now I want to join real payments with dummy/missing payments
      -- to get payment data for each month in the year.
      with cust as
      (
      select distinct CustomerID
      from @CustomerPayments
      )
      select * from @CustomerPayments cp
      union
      select c.CustomerID,
      (select dp.MonthNumber
      from @DummyPayments dp
      where dp.MonthNumber not in (select cp.MonthNumber from @CustomerPayments cp where cp.CustomerID = c.CustomerID)),
      0
      from cust c


      When I run it I get an error




      Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.




      I thought doing this with a union would work and I understand the error is telling me I'm getting too many results in each sub-query but short of using a cursor I can't work out how to do this. Perhaps I'm over complicating it but if anyone can help me out I'd appreciate it.







      sql sql-server






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Mar 25 at 5:03









      marc_s

      593k13311361279




      593k13311361279










      asked Mar 25 at 1:13









      nzmikenzmike

      2051617




      2051617






















          1 Answer
          1






          active

          oldest

          votes


















          3














          Use cross join to generate the rows and then left join to bring in the existing results:



          select c.customerid, dp.monthnumber, coalesce(cp.payment, 0) as payment
          from (select distinct customerid from @customerpayments cp
          ) c cross join
          @dummypayments dp left join
          @customerpayments cp
          on cp.customerid = c.customerid and
          cp.monthnumber = dp.monthnumber;





          share|improve this answer























          • Wow, nice work - thanks for the quick reply. I haven't ever really used CROSS JOIN much so that didn't even cross my mind but that's nice. How would it scale up on a large dataset though - isn't cross join very expensive?

            – nzmike
            Mar 25 at 4:04












          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%2f55330159%2fmerging-dummy-placeholder-data-into-a-sql-query%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









          3














          Use cross join to generate the rows and then left join to bring in the existing results:



          select c.customerid, dp.monthnumber, coalesce(cp.payment, 0) as payment
          from (select distinct customerid from @customerpayments cp
          ) c cross join
          @dummypayments dp left join
          @customerpayments cp
          on cp.customerid = c.customerid and
          cp.monthnumber = dp.monthnumber;





          share|improve this answer























          • Wow, nice work - thanks for the quick reply. I haven't ever really used CROSS JOIN much so that didn't even cross my mind but that's nice. How would it scale up on a large dataset though - isn't cross join very expensive?

            – nzmike
            Mar 25 at 4:04
















          3














          Use cross join to generate the rows and then left join to bring in the existing results:



          select c.customerid, dp.monthnumber, coalesce(cp.payment, 0) as payment
          from (select distinct customerid from @customerpayments cp
          ) c cross join
          @dummypayments dp left join
          @customerpayments cp
          on cp.customerid = c.customerid and
          cp.monthnumber = dp.monthnumber;





          share|improve this answer























          • Wow, nice work - thanks for the quick reply. I haven't ever really used CROSS JOIN much so that didn't even cross my mind but that's nice. How would it scale up on a large dataset though - isn't cross join very expensive?

            – nzmike
            Mar 25 at 4:04














          3












          3








          3







          Use cross join to generate the rows and then left join to bring in the existing results:



          select c.customerid, dp.monthnumber, coalesce(cp.payment, 0) as payment
          from (select distinct customerid from @customerpayments cp
          ) c cross join
          @dummypayments dp left join
          @customerpayments cp
          on cp.customerid = c.customerid and
          cp.monthnumber = dp.monthnumber;





          share|improve this answer













          Use cross join to generate the rows and then left join to bring in the existing results:



          select c.customerid, dp.monthnumber, coalesce(cp.payment, 0) as payment
          from (select distinct customerid from @customerpayments cp
          ) c cross join
          @dummypayments dp left join
          @customerpayments cp
          on cp.customerid = c.customerid and
          cp.monthnumber = dp.monthnumber;






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Mar 25 at 1:16









          Gordon LinoffGordon Linoff

          822k38333441




          822k38333441












          • Wow, nice work - thanks for the quick reply. I haven't ever really used CROSS JOIN much so that didn't even cross my mind but that's nice. How would it scale up on a large dataset though - isn't cross join very expensive?

            – nzmike
            Mar 25 at 4:04


















          • Wow, nice work - thanks for the quick reply. I haven't ever really used CROSS JOIN much so that didn't even cross my mind but that's nice. How would it scale up on a large dataset though - isn't cross join very expensive?

            – nzmike
            Mar 25 at 4:04

















          Wow, nice work - thanks for the quick reply. I haven't ever really used CROSS JOIN much so that didn't even cross my mind but that's nice. How would it scale up on a large dataset though - isn't cross join very expensive?

          – nzmike
          Mar 25 at 4:04






          Wow, nice work - thanks for the quick reply. I haven't ever really used CROSS JOIN much so that didn't even cross my mind but that's nice. How would it scale up on a large dataset though - isn't cross join very expensive?

          – nzmike
          Mar 25 at 4:04




















          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%2f55330159%2fmerging-dummy-placeholder-data-into-a-sql-query%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

          Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

          Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

          Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript