How to get all months in a query where one month has no matches?New query slower even if it has less logical reads than the old oneWhy SELECT COUNT() query execution plan includes left joined table?How to fill gaps with calendar table, count and group byNeed Help With SQL Server 2008 Join With 3 TablesFilling Empty Values when Calculating Standard DeviationSum by Implicit GroupAre there any other ways to get results from Two tables without using Sub QueryWill table partitions help me?How to bring data from two tables that could/could not be present in one of themSlow query on large table with 50M plus data (especially with larger offset)

What is the maximal acceptable delay between pilot's input and flight control surface actuation?

co-son-in-law or co-brother

Is mathematics truth?

Why do modes sound so different, although they are basically the same as a mode of another scale?

Do we know the problems the University of Manchester's Transistor Computer was intended to solve?

Can there be plants on the dark side of a tidally locked world?

Does secure hashing imply secure symmetric encryption?

Can a Beholder face its Antimagic Cone behind itself?

Why don't they build airplanes from 3D printer plastic?

Why not use futuristic pavise ballistic shields for protection?

Why do old games use flashing as means of showing damage?

Calculus Books, preferably Soviet.

Why do we need explainable AI?

How to find better food in airports

How did Gollum know Sauron was gathering the Haradrim to make war?

Divide Numbers by 0

What is the significance of 104%?

Is torque as fundamental a concept as force?

Does the Scrying spell require you to have a clear path to the target in order to work?

What percentage of the mass/energy of the universe is in the form of electromagnetic waves?

Which is the best password hashing algorithm in .NET Core?

How to annoymously report the Establishment Clause being broken?

Remove ads in Viber for PC

Why did the VIC-II and SID use 6 µm technology in the era of 3 µm and 1.5 µm?



How to get all months in a query where one month has no matches?


New query slower even if it has less logical reads than the old oneWhy SELECT COUNT() query execution plan includes left joined table?How to fill gaps with calendar table, count and group byNeed Help With SQL Server 2008 Join With 3 TablesFilling Empty Values when Calculating Standard DeviationSum by Implicit GroupAre there any other ways to get results from Two tables without using Sub QueryWill table partitions help me?How to bring data from two tables that could/could not be present in one of themSlow query on large table with 50M plus data (especially with larger offset)






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








1















I need to obtain every month by year (to fill up a graph). However, I found out that the first month had no data whatsoever and I wanna reflect that. The query is this one:



SELECT tblMes.id, COUNT(*) AS ingreso
FROM tblTicket
LEFT JOIN tblMes ON MONTH(tblTicket.fechaIngreso) = tblMes.id
WHERE year(fechaIngreso) = 2017
GROUP BY tblMes.id
ORDER BY tblMes.id asc


The result of the query is this one:



Month | Qty
--------------
"2" | "1066"
"3" | "1395"
"4" | "761"
"5" | "1316"
"6" | "879"
"7" | "1039"
"8" | "1099"
"9" | "577"
"10" | "1064"
"11" | "1268"
"12" | "1188"


The first row should be "1" | "0"



Why is the left join not enough?










share|improve this question
























  • If I’ve understood correctly you could use a RIGHT JOIN instead of LEFT (or swap to select from tblMes first if that’s where the months are listed).

    – JShark
    8 hours ago






  • 1





    @JShark Yes, you could swap the tables, or change to RIGHT JOIN, but you also have to change the WHERE clause to AND.

    – Aaron Bertrand
    8 hours ago

















1















I need to obtain every month by year (to fill up a graph). However, I found out that the first month had no data whatsoever and I wanna reflect that. The query is this one:



SELECT tblMes.id, COUNT(*) AS ingreso
FROM tblTicket
LEFT JOIN tblMes ON MONTH(tblTicket.fechaIngreso) = tblMes.id
WHERE year(fechaIngreso) = 2017
GROUP BY tblMes.id
ORDER BY tblMes.id asc


The result of the query is this one:



Month | Qty
--------------
"2" | "1066"
"3" | "1395"
"4" | "761"
"5" | "1316"
"6" | "879"
"7" | "1039"
"8" | "1099"
"9" | "577"
"10" | "1064"
"11" | "1268"
"12" | "1188"


The first row should be "1" | "0"



Why is the left join not enough?










share|improve this question
























  • If I’ve understood correctly you could use a RIGHT JOIN instead of LEFT (or swap to select from tblMes first if that’s where the months are listed).

    – JShark
    8 hours ago






  • 1





    @JShark Yes, you could swap the tables, or change to RIGHT JOIN, but you also have to change the WHERE clause to AND.

    – Aaron Bertrand
    8 hours ago













1












1








1


1






I need to obtain every month by year (to fill up a graph). However, I found out that the first month had no data whatsoever and I wanna reflect that. The query is this one:



SELECT tblMes.id, COUNT(*) AS ingreso
FROM tblTicket
LEFT JOIN tblMes ON MONTH(tblTicket.fechaIngreso) = tblMes.id
WHERE year(fechaIngreso) = 2017
GROUP BY tblMes.id
ORDER BY tblMes.id asc


The result of the query is this one:



Month | Qty
--------------
"2" | "1066"
"3" | "1395"
"4" | "761"
"5" | "1316"
"6" | "879"
"7" | "1039"
"8" | "1099"
"9" | "577"
"10" | "1064"
"11" | "1268"
"12" | "1188"


The first row should be "1" | "0"



Why is the left join not enough?










share|improve this question














I need to obtain every month by year (to fill up a graph). However, I found out that the first month had no data whatsoever and I wanna reflect that. The query is this one:



SELECT tblMes.id, COUNT(*) AS ingreso
FROM tblTicket
LEFT JOIN tblMes ON MONTH(tblTicket.fechaIngreso) = tblMes.id
WHERE year(fechaIngreso) = 2017
GROUP BY tblMes.id
ORDER BY tblMes.id asc


The result of the query is this one:



Month | Qty
--------------
"2" | "1066"
"3" | "1395"
"4" | "761"
"5" | "1316"
"6" | "879"
"7" | "1039"
"8" | "1099"
"9" | "577"
"10" | "1064"
"11" | "1268"
"12" | "1188"


The first row should be "1" | "0"



Why is the left join not enough?







sql-server






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 8 hours ago









ffuentesffuentes

1186 bronze badges




1186 bronze badges















  • If I’ve understood correctly you could use a RIGHT JOIN instead of LEFT (or swap to select from tblMes first if that’s where the months are listed).

    – JShark
    8 hours ago






  • 1





    @JShark Yes, you could swap the tables, or change to RIGHT JOIN, but you also have to change the WHERE clause to AND.

    – Aaron Bertrand
    8 hours ago

















  • If I’ve understood correctly you could use a RIGHT JOIN instead of LEFT (or swap to select from tblMes first if that’s where the months are listed).

    – JShark
    8 hours ago






  • 1





    @JShark Yes, you could swap the tables, or change to RIGHT JOIN, but you also have to change the WHERE clause to AND.

    – Aaron Bertrand
    8 hours ago
















If I’ve understood correctly you could use a RIGHT JOIN instead of LEFT (or swap to select from tblMes first if that’s where the months are listed).

– JShark
8 hours ago





If I’ve understood correctly you could use a RIGHT JOIN instead of LEFT (or swap to select from tblMes first if that’s where the months are listed).

– JShark
8 hours ago




1




1





@JShark Yes, you could swap the tables, or change to RIGHT JOIN, but you also have to change the WHERE clause to AND.

– Aaron Bertrand
8 hours ago





@JShark Yes, you could swap the tables, or change to RIGHT JOIN, but you also have to change the WHERE clause to AND.

– Aaron Bertrand
8 hours ago










2 Answers
2






active

oldest

votes


















6















I think you just had your tables backwards (the first table is all the rows you want, the outer table is all the rows that might exist). You also need the outer table clauses to be part of the join criteria (ON), rather than filter criteria (WHERE), otherwise your outer join turns into an inner join.



SELECT m.id, COUNT(t.fechaIngreso) AS ingreso
FROM dbo.tblMes AS m
LEFT OUTER JOIN dbo.tblTicket AS t
ON MONTH(t.fechaIngreso) = m.id
AND year(t.fechaIngreso) = 2017
GROUP BY m.id
ORDER BY m.id;


This is assuming tblMes is just a table with 12 rows, with one row for each of the 12 months. You can also do this without that table pretty easily:



;WITH Months(id) AS
(
SELECT 1 UNION ALL SELECT id+1 FROM Months WHERE id <= 11
)
SELECT m.id, COUNT(t.fechaIngreso) AS ingreso
FROM Months AS m
LEFT OUTER JOIN dbo.tblTicket AS t
ON m.id = MONTH(t.fechaIngreso)
AND YEAR(t.fechaIngreso) = 2017
GROUP BY m.id
ORDER BY m.id;





share|improve this answer



























  • Yes, exactly. tblMes is a table with month ids and names

    – ffuentes
    8 hours ago


















2















Since you did not provide either table definitions nor sample data, it's not easy to guess. The easiest way is to add a default row for each month, and then pick the max for that month. Something more elegant is likely possible, but it is impossible to guess what that would be:



SELECT MONTH, MAX(CNT)
FROM (
SELECT tblMes.id AS MONTH, COUNT(*) AS CNT
FROM tblTicket
LEFT JOIN tblMes ON MONTH(tblTicket.fechaIngreso) = tblMes.id
WHERE year(fechaIngreso) = 2017
GROUP BY tblMes.id
UNION SELECT 1, 0
UNION SELECT 2, 0
UNION ...
...
) AS X
GROUP BY MONTH
ORDER BY MONTH;





share|improve this answer



























    Your Answer








    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "182"
    ;
    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: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    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%2fdba.stackexchange.com%2fquestions%2f246795%2fhow-to-get-all-months-in-a-query-where-one-month-has-no-matches%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









    6















    I think you just had your tables backwards (the first table is all the rows you want, the outer table is all the rows that might exist). You also need the outer table clauses to be part of the join criteria (ON), rather than filter criteria (WHERE), otherwise your outer join turns into an inner join.



    SELECT m.id, COUNT(t.fechaIngreso) AS ingreso
    FROM dbo.tblMes AS m
    LEFT OUTER JOIN dbo.tblTicket AS t
    ON MONTH(t.fechaIngreso) = m.id
    AND year(t.fechaIngreso) = 2017
    GROUP BY m.id
    ORDER BY m.id;


    This is assuming tblMes is just a table with 12 rows, with one row for each of the 12 months. You can also do this without that table pretty easily:



    ;WITH Months(id) AS
    (
    SELECT 1 UNION ALL SELECT id+1 FROM Months WHERE id <= 11
    )
    SELECT m.id, COUNT(t.fechaIngreso) AS ingreso
    FROM Months AS m
    LEFT OUTER JOIN dbo.tblTicket AS t
    ON m.id = MONTH(t.fechaIngreso)
    AND YEAR(t.fechaIngreso) = 2017
    GROUP BY m.id
    ORDER BY m.id;





    share|improve this answer



























    • Yes, exactly. tblMes is a table with month ids and names

      – ffuentes
      8 hours ago















    6















    I think you just had your tables backwards (the first table is all the rows you want, the outer table is all the rows that might exist). You also need the outer table clauses to be part of the join criteria (ON), rather than filter criteria (WHERE), otherwise your outer join turns into an inner join.



    SELECT m.id, COUNT(t.fechaIngreso) AS ingreso
    FROM dbo.tblMes AS m
    LEFT OUTER JOIN dbo.tblTicket AS t
    ON MONTH(t.fechaIngreso) = m.id
    AND year(t.fechaIngreso) = 2017
    GROUP BY m.id
    ORDER BY m.id;


    This is assuming tblMes is just a table with 12 rows, with one row for each of the 12 months. You can also do this without that table pretty easily:



    ;WITH Months(id) AS
    (
    SELECT 1 UNION ALL SELECT id+1 FROM Months WHERE id <= 11
    )
    SELECT m.id, COUNT(t.fechaIngreso) AS ingreso
    FROM Months AS m
    LEFT OUTER JOIN dbo.tblTicket AS t
    ON m.id = MONTH(t.fechaIngreso)
    AND YEAR(t.fechaIngreso) = 2017
    GROUP BY m.id
    ORDER BY m.id;





    share|improve this answer



























    • Yes, exactly. tblMes is a table with month ids and names

      – ffuentes
      8 hours ago













    6














    6










    6









    I think you just had your tables backwards (the first table is all the rows you want, the outer table is all the rows that might exist). You also need the outer table clauses to be part of the join criteria (ON), rather than filter criteria (WHERE), otherwise your outer join turns into an inner join.



    SELECT m.id, COUNT(t.fechaIngreso) AS ingreso
    FROM dbo.tblMes AS m
    LEFT OUTER JOIN dbo.tblTicket AS t
    ON MONTH(t.fechaIngreso) = m.id
    AND year(t.fechaIngreso) = 2017
    GROUP BY m.id
    ORDER BY m.id;


    This is assuming tblMes is just a table with 12 rows, with one row for each of the 12 months. You can also do this without that table pretty easily:



    ;WITH Months(id) AS
    (
    SELECT 1 UNION ALL SELECT id+1 FROM Months WHERE id <= 11
    )
    SELECT m.id, COUNT(t.fechaIngreso) AS ingreso
    FROM Months AS m
    LEFT OUTER JOIN dbo.tblTicket AS t
    ON m.id = MONTH(t.fechaIngreso)
    AND YEAR(t.fechaIngreso) = 2017
    GROUP BY m.id
    ORDER BY m.id;





    share|improve this answer















    I think you just had your tables backwards (the first table is all the rows you want, the outer table is all the rows that might exist). You also need the outer table clauses to be part of the join criteria (ON), rather than filter criteria (WHERE), otherwise your outer join turns into an inner join.



    SELECT m.id, COUNT(t.fechaIngreso) AS ingreso
    FROM dbo.tblMes AS m
    LEFT OUTER JOIN dbo.tblTicket AS t
    ON MONTH(t.fechaIngreso) = m.id
    AND year(t.fechaIngreso) = 2017
    GROUP BY m.id
    ORDER BY m.id;


    This is assuming tblMes is just a table with 12 rows, with one row for each of the 12 months. You can also do this without that table pretty easily:



    ;WITH Months(id) AS
    (
    SELECT 1 UNION ALL SELECT id+1 FROM Months WHERE id <= 11
    )
    SELECT m.id, COUNT(t.fechaIngreso) AS ingreso
    FROM Months AS m
    LEFT OUTER JOIN dbo.tblTicket AS t
    ON m.id = MONTH(t.fechaIngreso)
    AND YEAR(t.fechaIngreso) = 2017
    GROUP BY m.id
    ORDER BY m.id;






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 7 hours ago

























    answered 8 hours ago









    Aaron BertrandAaron Bertrand

    160k19 gold badges319 silver badges523 bronze badges




    160k19 gold badges319 silver badges523 bronze badges















    • Yes, exactly. tblMes is a table with month ids and names

      – ffuentes
      8 hours ago

















    • Yes, exactly. tblMes is a table with month ids and names

      – ffuentes
      8 hours ago
















    Yes, exactly. tblMes is a table with month ids and names

    – ffuentes
    8 hours ago





    Yes, exactly. tblMes is a table with month ids and names

    – ffuentes
    8 hours ago













    2















    Since you did not provide either table definitions nor sample data, it's not easy to guess. The easiest way is to add a default row for each month, and then pick the max for that month. Something more elegant is likely possible, but it is impossible to guess what that would be:



    SELECT MONTH, MAX(CNT)
    FROM (
    SELECT tblMes.id AS MONTH, COUNT(*) AS CNT
    FROM tblTicket
    LEFT JOIN tblMes ON MONTH(tblTicket.fechaIngreso) = tblMes.id
    WHERE year(fechaIngreso) = 2017
    GROUP BY tblMes.id
    UNION SELECT 1, 0
    UNION SELECT 2, 0
    UNION ...
    ...
    ) AS X
    GROUP BY MONTH
    ORDER BY MONTH;





    share|improve this answer





























      2















      Since you did not provide either table definitions nor sample data, it's not easy to guess. The easiest way is to add a default row for each month, and then pick the max for that month. Something more elegant is likely possible, but it is impossible to guess what that would be:



      SELECT MONTH, MAX(CNT)
      FROM (
      SELECT tblMes.id AS MONTH, COUNT(*) AS CNT
      FROM tblTicket
      LEFT JOIN tblMes ON MONTH(tblTicket.fechaIngreso) = tblMes.id
      WHERE year(fechaIngreso) = 2017
      GROUP BY tblMes.id
      UNION SELECT 1, 0
      UNION SELECT 2, 0
      UNION ...
      ...
      ) AS X
      GROUP BY MONTH
      ORDER BY MONTH;





      share|improve this answer



























        2














        2










        2









        Since you did not provide either table definitions nor sample data, it's not easy to guess. The easiest way is to add a default row for each month, and then pick the max for that month. Something more elegant is likely possible, but it is impossible to guess what that would be:



        SELECT MONTH, MAX(CNT)
        FROM (
        SELECT tblMes.id AS MONTH, COUNT(*) AS CNT
        FROM tblTicket
        LEFT JOIN tblMes ON MONTH(tblTicket.fechaIngreso) = tblMes.id
        WHERE year(fechaIngreso) = 2017
        GROUP BY tblMes.id
        UNION SELECT 1, 0
        UNION SELECT 2, 0
        UNION ...
        ...
        ) AS X
        GROUP BY MONTH
        ORDER BY MONTH;





        share|improve this answer













        Since you did not provide either table definitions nor sample data, it's not easy to guess. The easiest way is to add a default row for each month, and then pick the max for that month. Something more elegant is likely possible, but it is impossible to guess what that would be:



        SELECT MONTH, MAX(CNT)
        FROM (
        SELECT tblMes.id AS MONTH, COUNT(*) AS CNT
        FROM tblTicket
        LEFT JOIN tblMes ON MONTH(tblTicket.fechaIngreso) = tblMes.id
        WHERE year(fechaIngreso) = 2017
        GROUP BY tblMes.id
        UNION SELECT 1, 0
        UNION SELECT 2, 0
        UNION ...
        ...
        ) AS X
        GROUP BY MONTH
        ORDER BY MONTH;






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 8 hours ago









        LennartLennart

        14.5k2 gold badges13 silver badges44 bronze badges




        14.5k2 gold badges13 silver badges44 bronze badges






























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Database Administrators Stack Exchange!


            • 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%2fdba.stackexchange.com%2fquestions%2f246795%2fhow-to-get-all-months-in-a-query-where-one-month-has-no-matches%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

            ParseJSON using SSJSUsing AMPscript with SSJS ActivitiesHow to resubscribe a user in Marketing cloud using SSJS?Pulling Subscriber Status from Lists using SSJSRetrieving Emails using SSJSProblem in updating DE using SSJSUsing SSJS to send single email in Marketing CloudError adding EmailSendDefinition using SSJS

            Кампала Садржај Географија Географија Историја Становништво Привреда Партнерски градови Референце Спољашње везе Мени за навигацију0°11′ СГШ; 32°20′ ИГД / 0.18° СГШ; 32.34° ИГД / 0.18; 32.340°11′ СГШ; 32°20′ ИГД / 0.18° СГШ; 32.34° ИГД / 0.18; 32.34МедијиПодациЗванични веб-сајту

            19. јануар Садржај Догађаји Рођења Смрти Празници и дани сећања Види још Референце Мени за навигацијуу