Strange behaviour of Sql query with between operator









up vote
-2
down vote

favorite












There is this strange error in sql query.



The query is something like this.



select * from student where dob between '20150820' and '20150828'


But in the database the column of dob is varchar(14) and is in yyyyMMddhhmmss format,Say my data in the row is (20150827142545).If i fire the above query it should not retrive any rows as i have mentioned yyyyMMdd format in the query.But it retrives the row with yesterday date (i.e 20150827112535) and it cannot get the records with today's date (i.e 20150828144532)



Why is this happening??



Thanks for the help in advance










share|improve this question

















  • 1




    You do string comparison not date, convert to date and should work. And for future please don't store date as VARCHAR(14)
    – Lukasz Szozda
    Aug 28 '15 at 7:44







  • 2




    Alter column to date type!
    – jarlh
    Aug 28 '15 at 7:44






  • 4




    There is nothing strange going on. If you store a date as a varchar you cannot expect it to behave like a date.
    – Fred
    Aug 28 '15 at 7:46










  • Thanks for giving suggestions..... Data type cannot be converted since it is in production now.. @jarlh
    – bhanu.cs
    Aug 28 '15 at 8:51










  • @Fred right I agree ... But why is it showing me the records of yesterday?? This is my actual question..
    – bhanu.cs
    Aug 28 '15 at 8:52














up vote
-2
down vote

favorite












There is this strange error in sql query.



The query is something like this.



select * from student where dob between '20150820' and '20150828'


But in the database the column of dob is varchar(14) and is in yyyyMMddhhmmss format,Say my data in the row is (20150827142545).If i fire the above query it should not retrive any rows as i have mentioned yyyyMMdd format in the query.But it retrives the row with yesterday date (i.e 20150827112535) and it cannot get the records with today's date (i.e 20150828144532)



Why is this happening??



Thanks for the help in advance










share|improve this question

















  • 1




    You do string comparison not date, convert to date and should work. And for future please don't store date as VARCHAR(14)
    – Lukasz Szozda
    Aug 28 '15 at 7:44







  • 2




    Alter column to date type!
    – jarlh
    Aug 28 '15 at 7:44






  • 4




    There is nothing strange going on. If you store a date as a varchar you cannot expect it to behave like a date.
    – Fred
    Aug 28 '15 at 7:46










  • Thanks for giving suggestions..... Data type cannot be converted since it is in production now.. @jarlh
    – bhanu.cs
    Aug 28 '15 at 8:51










  • @Fred right I agree ... But why is it showing me the records of yesterday?? This is my actual question..
    – bhanu.cs
    Aug 28 '15 at 8:52












up vote
-2
down vote

favorite









up vote
-2
down vote

favorite











There is this strange error in sql query.



The query is something like this.



select * from student where dob between '20150820' and '20150828'


But in the database the column of dob is varchar(14) and is in yyyyMMddhhmmss format,Say my data in the row is (20150827142545).If i fire the above query it should not retrive any rows as i have mentioned yyyyMMdd format in the query.But it retrives the row with yesterday date (i.e 20150827112535) and it cannot get the records with today's date (i.e 20150828144532)



Why is this happening??



Thanks for the help in advance










share|improve this question













There is this strange error in sql query.



The query is something like this.



select * from student where dob between '20150820' and '20150828'


But in the database the column of dob is varchar(14) and is in yyyyMMddhhmmss format,Say my data in the row is (20150827142545).If i fire the above query it should not retrive any rows as i have mentioned yyyyMMdd format in the query.But it retrives the row with yesterday date (i.e 20150827112535) and it cannot get the records with today's date (i.e 20150828144532)



Why is this happening??



Thanks for the help in advance







sql sql-server






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Aug 28 '15 at 7:42









bhanu.cs

8461623




8461623







  • 1




    You do string comparison not date, convert to date and should work. And for future please don't store date as VARCHAR(14)
    – Lukasz Szozda
    Aug 28 '15 at 7:44







  • 2




    Alter column to date type!
    – jarlh
    Aug 28 '15 at 7:44






  • 4




    There is nothing strange going on. If you store a date as a varchar you cannot expect it to behave like a date.
    – Fred
    Aug 28 '15 at 7:46










  • Thanks for giving suggestions..... Data type cannot be converted since it is in production now.. @jarlh
    – bhanu.cs
    Aug 28 '15 at 8:51










  • @Fred right I agree ... But why is it showing me the records of yesterday?? This is my actual question..
    – bhanu.cs
    Aug 28 '15 at 8:52












  • 1




    You do string comparison not date, convert to date and should work. And for future please don't store date as VARCHAR(14)
    – Lukasz Szozda
    Aug 28 '15 at 7:44







  • 2




    Alter column to date type!
    – jarlh
    Aug 28 '15 at 7:44






  • 4




    There is nothing strange going on. If you store a date as a varchar you cannot expect it to behave like a date.
    – Fred
    Aug 28 '15 at 7:46










  • Thanks for giving suggestions..... Data type cannot be converted since it is in production now.. @jarlh
    – bhanu.cs
    Aug 28 '15 at 8:51










  • @Fred right I agree ... But why is it showing me the records of yesterday?? This is my actual question..
    – bhanu.cs
    Aug 28 '15 at 8:52







1




1




You do string comparison not date, convert to date and should work. And for future please don't store date as VARCHAR(14)
– Lukasz Szozda
Aug 28 '15 at 7:44





You do string comparison not date, convert to date and should work. And for future please don't store date as VARCHAR(14)
– Lukasz Szozda
Aug 28 '15 at 7:44





2




2




Alter column to date type!
– jarlh
Aug 28 '15 at 7:44




Alter column to date type!
– jarlh
Aug 28 '15 at 7:44




4




4




There is nothing strange going on. If you store a date as a varchar you cannot expect it to behave like a date.
– Fred
Aug 28 '15 at 7:46




There is nothing strange going on. If you store a date as a varchar you cannot expect it to behave like a date.
– Fred
Aug 28 '15 at 7:46












Thanks for giving suggestions..... Data type cannot be converted since it is in production now.. @jarlh
– bhanu.cs
Aug 28 '15 at 8:51




Thanks for giving suggestions..... Data type cannot be converted since it is in production now.. @jarlh
– bhanu.cs
Aug 28 '15 at 8:51












@Fred right I agree ... But why is it showing me the records of yesterday?? This is my actual question..
– bhanu.cs
Aug 28 '15 at 8:52




@Fred right I agree ... But why is it showing me the records of yesterday?? This is my actual question..
– bhanu.cs
Aug 28 '15 at 8:52












5 Answers
5






active

oldest

votes

















up vote
1
down vote













You can try like this:



select * from student 
where convert(date,LEFT(dob,8)) between
convert(date'20150820') and convert(date,'20150828'))


Also as others have commented you need to store your date as Date instead of varchar to avoid such problems in future.






share|improve this answer




















  • Thank you..... But my question is why is it showing records for yesterday's date with my wrong query??
    – bhanu.cs
    Aug 28 '15 at 8:57










  • @BhanuChowdary:- The reason is probably because BETWEEN is asymmetric in SQL Server and dates were compared as strings not as a dates
    – Rahul Tripathi
    Aug 28 '15 at 9:05










  • :- Yeah ..true.. Dates are compared as strings but why and how is the query giving me the records between those dates exclusive of the dates specified in the query and, even the strings are in yyyyMMddhhmmss format.But In the query I have specified in yyyyMmdd format only.How is it making a match for the records between the specified dates??
    – bhanu.cs
    Aug 28 '15 at 9:16










  • @BhanuChowdary:- Its probably because BETWEEN returns TRUE if the value of test_expression is greater than or equal to the value of begin_expression and less than or equal to the value of end_expression. So in your case it is matching the first 8 characters and returns true and so you are getting the result.
    – Rahul Tripathi
    Aug 28 '15 at 9:26










  • Ok.... Thank You very much ...
    – bhanu.cs
    Aug 28 '15 at 9:29

















up vote
1
down vote













As already mentioned you would need to use the correct date type to have between behave properly.



select *
from student
where convert(date,LEFT(dob,8)) between '20150820' and '20150828'


Sidenote: You don't have to explicitly convert your two dates from text as this will be done implicitly as long as you use an unambiguous date representation, i.e. the ISO standard 'YYYYMMDD' or 'YYYY-MM-DD'. Of course if you're holding the values in variables then use date | datetime datatype



declare @startdate date
declare @enddate date

select *
from student
where convert(date,LEFT(dob,8)) between @startdate and @enddate


Sidenote 2: Performing the functions on your table dob column would prevent any indexes on that column from being used to their full potential in your execution plan and may result in slower execution, if you can, define the correct data type for the table dob column or use a persistent computed column or materialised view if your performance is a real issue.



Sidenote 3: If you need to maintain the time portion in your data i.e. date and time of birth, use the following to ensure all records are captured;



select *
from student
where
convert(date,LEFT(dob,8)) >= '20150820'
and convert(date,LEFT(dob,8)) < dateadd(d,1,'20150828')





share|improve this answer
















  • 1




    Thank you Edward.... I know it can be done using convert function ...But my question here is that how is the query behaving if it is of type varchar...Why is it showing me the records between those days exclusive of the dates i have mentioned in the query ..
    – bhanu.cs
    Aug 28 '15 at 9:04






  • 1




    I see what your asking, well I understand that when comparing character data it would start from the very left string and when strings are of unequal length the longer string is treated as being after. This is why your first date appears and second doesn't. In other words AB comes before ABC and ABC comes before AC and the same for numbers 12 comes before 123 and 123 comes before 13. Back to your original data 20150827142545 is between 20150827[------] and 20150828[------] whilst 20150828144532 comes after 20150828[------] and is therefore excluded from the result set.
    – Edward Comeau
    Aug 28 '15 at 9:25










  • Ohhh... Ok Thank You very much got it .... :)
    – bhanu.cs
    Aug 28 '15 at 9:28










  • Also, I think that the ordering of character data is defined by the character set in use and areas such as case sensitivity can come into play. I'm trying to find the links to back this up
    – Edward Comeau
    Aug 28 '15 at 9:30

















up vote
0
down vote













All you have to do is to convert first the string to date.



select * 
from student
where dob between convert(date, '20150820') and convert(date, '20150828')





share|improve this answer





























    up vote
    0
    down vote













    Why is this happening?



    The comparison is executed from left to right and the order of characters is determined by the codepage in use.




    Sort Order



    Sort order specifies the way that data values are sorted, affecting
    the results of data comparison. The sorting of data is accomplished
    through collations, and it can be optimized using indexes.




    https://msdn.microsoft.com/en-us/library/ms143726.aspx






    share|improve this answer



























      up vote
      -2
      down vote













      There are problems with between in T-SQL.



      But if you want a fast answer convert to date first and use >= <= or even datediff to compare - maybe write a between function yourself if you want the easy use like between and no care about begin and start times ...



      • What do BETWEEN and the devil have in common?





      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',
        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%2f32265817%2fstrange-behaviour-of-sql-query-with-between-operator%23new-answer', 'question_page');

        );

        Post as a guest















        Required, but never shown

























        5 Answers
        5






        active

        oldest

        votes








        5 Answers
        5






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes








        up vote
        1
        down vote













        You can try like this:



        select * from student 
        where convert(date,LEFT(dob,8)) between
        convert(date'20150820') and convert(date,'20150828'))


        Also as others have commented you need to store your date as Date instead of varchar to avoid such problems in future.






        share|improve this answer




















        • Thank you..... But my question is why is it showing records for yesterday's date with my wrong query??
          – bhanu.cs
          Aug 28 '15 at 8:57










        • @BhanuChowdary:- The reason is probably because BETWEEN is asymmetric in SQL Server and dates were compared as strings not as a dates
          – Rahul Tripathi
          Aug 28 '15 at 9:05










        • :- Yeah ..true.. Dates are compared as strings but why and how is the query giving me the records between those dates exclusive of the dates specified in the query and, even the strings are in yyyyMMddhhmmss format.But In the query I have specified in yyyyMmdd format only.How is it making a match for the records between the specified dates??
          – bhanu.cs
          Aug 28 '15 at 9:16










        • @BhanuChowdary:- Its probably because BETWEEN returns TRUE if the value of test_expression is greater than or equal to the value of begin_expression and less than or equal to the value of end_expression. So in your case it is matching the first 8 characters and returns true and so you are getting the result.
          – Rahul Tripathi
          Aug 28 '15 at 9:26










        • Ok.... Thank You very much ...
          – bhanu.cs
          Aug 28 '15 at 9:29














        up vote
        1
        down vote













        You can try like this:



        select * from student 
        where convert(date,LEFT(dob,8)) between
        convert(date'20150820') and convert(date,'20150828'))


        Also as others have commented you need to store your date as Date instead of varchar to avoid such problems in future.






        share|improve this answer




















        • Thank you..... But my question is why is it showing records for yesterday's date with my wrong query??
          – bhanu.cs
          Aug 28 '15 at 8:57










        • @BhanuChowdary:- The reason is probably because BETWEEN is asymmetric in SQL Server and dates were compared as strings not as a dates
          – Rahul Tripathi
          Aug 28 '15 at 9:05










        • :- Yeah ..true.. Dates are compared as strings but why and how is the query giving me the records between those dates exclusive of the dates specified in the query and, even the strings are in yyyyMMddhhmmss format.But In the query I have specified in yyyyMmdd format only.How is it making a match for the records between the specified dates??
          – bhanu.cs
          Aug 28 '15 at 9:16










        • @BhanuChowdary:- Its probably because BETWEEN returns TRUE if the value of test_expression is greater than or equal to the value of begin_expression and less than or equal to the value of end_expression. So in your case it is matching the first 8 characters and returns true and so you are getting the result.
          – Rahul Tripathi
          Aug 28 '15 at 9:26










        • Ok.... Thank You very much ...
          – bhanu.cs
          Aug 28 '15 at 9:29












        up vote
        1
        down vote










        up vote
        1
        down vote









        You can try like this:



        select * from student 
        where convert(date,LEFT(dob,8)) between
        convert(date'20150820') and convert(date,'20150828'))


        Also as others have commented you need to store your date as Date instead of varchar to avoid such problems in future.






        share|improve this answer












        You can try like this:



        select * from student 
        where convert(date,LEFT(dob,8)) between
        convert(date'20150820') and convert(date,'20150828'))


        Also as others have commented you need to store your date as Date instead of varchar to avoid such problems in future.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Aug 28 '15 at 7:48









        Rahul Tripathi

        125k19160232




        125k19160232











        • Thank you..... But my question is why is it showing records for yesterday's date with my wrong query??
          – bhanu.cs
          Aug 28 '15 at 8:57










        • @BhanuChowdary:- The reason is probably because BETWEEN is asymmetric in SQL Server and dates were compared as strings not as a dates
          – Rahul Tripathi
          Aug 28 '15 at 9:05










        • :- Yeah ..true.. Dates are compared as strings but why and how is the query giving me the records between those dates exclusive of the dates specified in the query and, even the strings are in yyyyMMddhhmmss format.But In the query I have specified in yyyyMmdd format only.How is it making a match for the records between the specified dates??
          – bhanu.cs
          Aug 28 '15 at 9:16










        • @BhanuChowdary:- Its probably because BETWEEN returns TRUE if the value of test_expression is greater than or equal to the value of begin_expression and less than or equal to the value of end_expression. So in your case it is matching the first 8 characters and returns true and so you are getting the result.
          – Rahul Tripathi
          Aug 28 '15 at 9:26










        • Ok.... Thank You very much ...
          – bhanu.cs
          Aug 28 '15 at 9:29
















        • Thank you..... But my question is why is it showing records for yesterday's date with my wrong query??
          – bhanu.cs
          Aug 28 '15 at 8:57










        • @BhanuChowdary:- The reason is probably because BETWEEN is asymmetric in SQL Server and dates were compared as strings not as a dates
          – Rahul Tripathi
          Aug 28 '15 at 9:05










        • :- Yeah ..true.. Dates are compared as strings but why and how is the query giving me the records between those dates exclusive of the dates specified in the query and, even the strings are in yyyyMMddhhmmss format.But In the query I have specified in yyyyMmdd format only.How is it making a match for the records between the specified dates??
          – bhanu.cs
          Aug 28 '15 at 9:16










        • @BhanuChowdary:- Its probably because BETWEEN returns TRUE if the value of test_expression is greater than or equal to the value of begin_expression and less than or equal to the value of end_expression. So in your case it is matching the first 8 characters and returns true and so you are getting the result.
          – Rahul Tripathi
          Aug 28 '15 at 9:26










        • Ok.... Thank You very much ...
          – bhanu.cs
          Aug 28 '15 at 9:29















        Thank you..... But my question is why is it showing records for yesterday's date with my wrong query??
        – bhanu.cs
        Aug 28 '15 at 8:57




        Thank you..... But my question is why is it showing records for yesterday's date with my wrong query??
        – bhanu.cs
        Aug 28 '15 at 8:57












        @BhanuChowdary:- The reason is probably because BETWEEN is asymmetric in SQL Server and dates were compared as strings not as a dates
        – Rahul Tripathi
        Aug 28 '15 at 9:05




        @BhanuChowdary:- The reason is probably because BETWEEN is asymmetric in SQL Server and dates were compared as strings not as a dates
        – Rahul Tripathi
        Aug 28 '15 at 9:05












        :- Yeah ..true.. Dates are compared as strings but why and how is the query giving me the records between those dates exclusive of the dates specified in the query and, even the strings are in yyyyMMddhhmmss format.But In the query I have specified in yyyyMmdd format only.How is it making a match for the records between the specified dates??
        – bhanu.cs
        Aug 28 '15 at 9:16




        :- Yeah ..true.. Dates are compared as strings but why and how is the query giving me the records between those dates exclusive of the dates specified in the query and, even the strings are in yyyyMMddhhmmss format.But In the query I have specified in yyyyMmdd format only.How is it making a match for the records between the specified dates??
        – bhanu.cs
        Aug 28 '15 at 9:16












        @BhanuChowdary:- Its probably because BETWEEN returns TRUE if the value of test_expression is greater than or equal to the value of begin_expression and less than or equal to the value of end_expression. So in your case it is matching the first 8 characters and returns true and so you are getting the result.
        – Rahul Tripathi
        Aug 28 '15 at 9:26




        @BhanuChowdary:- Its probably because BETWEEN returns TRUE if the value of test_expression is greater than or equal to the value of begin_expression and less than or equal to the value of end_expression. So in your case it is matching the first 8 characters and returns true and so you are getting the result.
        – Rahul Tripathi
        Aug 28 '15 at 9:26












        Ok.... Thank You very much ...
        – bhanu.cs
        Aug 28 '15 at 9:29




        Ok.... Thank You very much ...
        – bhanu.cs
        Aug 28 '15 at 9:29












        up vote
        1
        down vote













        As already mentioned you would need to use the correct date type to have between behave properly.



        select *
        from student
        where convert(date,LEFT(dob,8)) between '20150820' and '20150828'


        Sidenote: You don't have to explicitly convert your two dates from text as this will be done implicitly as long as you use an unambiguous date representation, i.e. the ISO standard 'YYYYMMDD' or 'YYYY-MM-DD'. Of course if you're holding the values in variables then use date | datetime datatype



        declare @startdate date
        declare @enddate date

        select *
        from student
        where convert(date,LEFT(dob,8)) between @startdate and @enddate


        Sidenote 2: Performing the functions on your table dob column would prevent any indexes on that column from being used to their full potential in your execution plan and may result in slower execution, if you can, define the correct data type for the table dob column or use a persistent computed column or materialised view if your performance is a real issue.



        Sidenote 3: If you need to maintain the time portion in your data i.e. date and time of birth, use the following to ensure all records are captured;



        select *
        from student
        where
        convert(date,LEFT(dob,8)) >= '20150820'
        and convert(date,LEFT(dob,8)) < dateadd(d,1,'20150828')





        share|improve this answer
















        • 1




          Thank you Edward.... I know it can be done using convert function ...But my question here is that how is the query behaving if it is of type varchar...Why is it showing me the records between those days exclusive of the dates i have mentioned in the query ..
          – bhanu.cs
          Aug 28 '15 at 9:04






        • 1




          I see what your asking, well I understand that when comparing character data it would start from the very left string and when strings are of unequal length the longer string is treated as being after. This is why your first date appears and second doesn't. In other words AB comes before ABC and ABC comes before AC and the same for numbers 12 comes before 123 and 123 comes before 13. Back to your original data 20150827142545 is between 20150827[------] and 20150828[------] whilst 20150828144532 comes after 20150828[------] and is therefore excluded from the result set.
          – Edward Comeau
          Aug 28 '15 at 9:25










        • Ohhh... Ok Thank You very much got it .... :)
          – bhanu.cs
          Aug 28 '15 at 9:28










        • Also, I think that the ordering of character data is defined by the character set in use and areas such as case sensitivity can come into play. I'm trying to find the links to back this up
          – Edward Comeau
          Aug 28 '15 at 9:30














        up vote
        1
        down vote













        As already mentioned you would need to use the correct date type to have between behave properly.



        select *
        from student
        where convert(date,LEFT(dob,8)) between '20150820' and '20150828'


        Sidenote: You don't have to explicitly convert your two dates from text as this will be done implicitly as long as you use an unambiguous date representation, i.e. the ISO standard 'YYYYMMDD' or 'YYYY-MM-DD'. Of course if you're holding the values in variables then use date | datetime datatype



        declare @startdate date
        declare @enddate date

        select *
        from student
        where convert(date,LEFT(dob,8)) between @startdate and @enddate


        Sidenote 2: Performing the functions on your table dob column would prevent any indexes on that column from being used to their full potential in your execution plan and may result in slower execution, if you can, define the correct data type for the table dob column or use a persistent computed column or materialised view if your performance is a real issue.



        Sidenote 3: If you need to maintain the time portion in your data i.e. date and time of birth, use the following to ensure all records are captured;



        select *
        from student
        where
        convert(date,LEFT(dob,8)) >= '20150820'
        and convert(date,LEFT(dob,8)) < dateadd(d,1,'20150828')





        share|improve this answer
















        • 1




          Thank you Edward.... I know it can be done using convert function ...But my question here is that how is the query behaving if it is of type varchar...Why is it showing me the records between those days exclusive of the dates i have mentioned in the query ..
          – bhanu.cs
          Aug 28 '15 at 9:04






        • 1




          I see what your asking, well I understand that when comparing character data it would start from the very left string and when strings are of unequal length the longer string is treated as being after. This is why your first date appears and second doesn't. In other words AB comes before ABC and ABC comes before AC and the same for numbers 12 comes before 123 and 123 comes before 13. Back to your original data 20150827142545 is between 20150827[------] and 20150828[------] whilst 20150828144532 comes after 20150828[------] and is therefore excluded from the result set.
          – Edward Comeau
          Aug 28 '15 at 9:25










        • Ohhh... Ok Thank You very much got it .... :)
          – bhanu.cs
          Aug 28 '15 at 9:28










        • Also, I think that the ordering of character data is defined by the character set in use and areas such as case sensitivity can come into play. I'm trying to find the links to back this up
          – Edward Comeau
          Aug 28 '15 at 9:30












        up vote
        1
        down vote










        up vote
        1
        down vote









        As already mentioned you would need to use the correct date type to have between behave properly.



        select *
        from student
        where convert(date,LEFT(dob,8)) between '20150820' and '20150828'


        Sidenote: You don't have to explicitly convert your two dates from text as this will be done implicitly as long as you use an unambiguous date representation, i.e. the ISO standard 'YYYYMMDD' or 'YYYY-MM-DD'. Of course if you're holding the values in variables then use date | datetime datatype



        declare @startdate date
        declare @enddate date

        select *
        from student
        where convert(date,LEFT(dob,8)) between @startdate and @enddate


        Sidenote 2: Performing the functions on your table dob column would prevent any indexes on that column from being used to their full potential in your execution plan and may result in slower execution, if you can, define the correct data type for the table dob column or use a persistent computed column or materialised view if your performance is a real issue.



        Sidenote 3: If you need to maintain the time portion in your data i.e. date and time of birth, use the following to ensure all records are captured;



        select *
        from student
        where
        convert(date,LEFT(dob,8)) >= '20150820'
        and convert(date,LEFT(dob,8)) < dateadd(d,1,'20150828')





        share|improve this answer












        As already mentioned you would need to use the correct date type to have between behave properly.



        select *
        from student
        where convert(date,LEFT(dob,8)) between '20150820' and '20150828'


        Sidenote: You don't have to explicitly convert your two dates from text as this will be done implicitly as long as you use an unambiguous date representation, i.e. the ISO standard 'YYYYMMDD' or 'YYYY-MM-DD'. Of course if you're holding the values in variables then use date | datetime datatype



        declare @startdate date
        declare @enddate date

        select *
        from student
        where convert(date,LEFT(dob,8)) between @startdate and @enddate


        Sidenote 2: Performing the functions on your table dob column would prevent any indexes on that column from being used to their full potential in your execution plan and may result in slower execution, if you can, define the correct data type for the table dob column or use a persistent computed column or materialised view if your performance is a real issue.



        Sidenote 3: If you need to maintain the time portion in your data i.e. date and time of birth, use the following to ensure all records are captured;



        select *
        from student
        where
        convert(date,LEFT(dob,8)) >= '20150820'
        and convert(date,LEFT(dob,8)) < dateadd(d,1,'20150828')






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Aug 28 '15 at 8:21









        Edward Comeau

        1,7611521




        1,7611521







        • 1




          Thank you Edward.... I know it can be done using convert function ...But my question here is that how is the query behaving if it is of type varchar...Why is it showing me the records between those days exclusive of the dates i have mentioned in the query ..
          – bhanu.cs
          Aug 28 '15 at 9:04






        • 1




          I see what your asking, well I understand that when comparing character data it would start from the very left string and when strings are of unequal length the longer string is treated as being after. This is why your first date appears and second doesn't. In other words AB comes before ABC and ABC comes before AC and the same for numbers 12 comes before 123 and 123 comes before 13. Back to your original data 20150827142545 is between 20150827[------] and 20150828[------] whilst 20150828144532 comes after 20150828[------] and is therefore excluded from the result set.
          – Edward Comeau
          Aug 28 '15 at 9:25










        • Ohhh... Ok Thank You very much got it .... :)
          – bhanu.cs
          Aug 28 '15 at 9:28










        • Also, I think that the ordering of character data is defined by the character set in use and areas such as case sensitivity can come into play. I'm trying to find the links to back this up
          – Edward Comeau
          Aug 28 '15 at 9:30












        • 1




          Thank you Edward.... I know it can be done using convert function ...But my question here is that how is the query behaving if it is of type varchar...Why is it showing me the records between those days exclusive of the dates i have mentioned in the query ..
          – bhanu.cs
          Aug 28 '15 at 9:04






        • 1




          I see what your asking, well I understand that when comparing character data it would start from the very left string and when strings are of unequal length the longer string is treated as being after. This is why your first date appears and second doesn't. In other words AB comes before ABC and ABC comes before AC and the same for numbers 12 comes before 123 and 123 comes before 13. Back to your original data 20150827142545 is between 20150827[------] and 20150828[------] whilst 20150828144532 comes after 20150828[------] and is therefore excluded from the result set.
          – Edward Comeau
          Aug 28 '15 at 9:25










        • Ohhh... Ok Thank You very much got it .... :)
          – bhanu.cs
          Aug 28 '15 at 9:28










        • Also, I think that the ordering of character data is defined by the character set in use and areas such as case sensitivity can come into play. I'm trying to find the links to back this up
          – Edward Comeau
          Aug 28 '15 at 9:30







        1




        1




        Thank you Edward.... I know it can be done using convert function ...But my question here is that how is the query behaving if it is of type varchar...Why is it showing me the records between those days exclusive of the dates i have mentioned in the query ..
        – bhanu.cs
        Aug 28 '15 at 9:04




        Thank you Edward.... I know it can be done using convert function ...But my question here is that how is the query behaving if it is of type varchar...Why is it showing me the records between those days exclusive of the dates i have mentioned in the query ..
        – bhanu.cs
        Aug 28 '15 at 9:04




        1




        1




        I see what your asking, well I understand that when comparing character data it would start from the very left string and when strings are of unequal length the longer string is treated as being after. This is why your first date appears and second doesn't. In other words AB comes before ABC and ABC comes before AC and the same for numbers 12 comes before 123 and 123 comes before 13. Back to your original data 20150827142545 is between 20150827[------] and 20150828[------] whilst 20150828144532 comes after 20150828[------] and is therefore excluded from the result set.
        – Edward Comeau
        Aug 28 '15 at 9:25




        I see what your asking, well I understand that when comparing character data it would start from the very left string and when strings are of unequal length the longer string is treated as being after. This is why your first date appears and second doesn't. In other words AB comes before ABC and ABC comes before AC and the same for numbers 12 comes before 123 and 123 comes before 13. Back to your original data 20150827142545 is between 20150827[------] and 20150828[------] whilst 20150828144532 comes after 20150828[------] and is therefore excluded from the result set.
        – Edward Comeau
        Aug 28 '15 at 9:25












        Ohhh... Ok Thank You very much got it .... :)
        – bhanu.cs
        Aug 28 '15 at 9:28




        Ohhh... Ok Thank You very much got it .... :)
        – bhanu.cs
        Aug 28 '15 at 9:28












        Also, I think that the ordering of character data is defined by the character set in use and areas such as case sensitivity can come into play. I'm trying to find the links to back this up
        – Edward Comeau
        Aug 28 '15 at 9:30




        Also, I think that the ordering of character data is defined by the character set in use and areas such as case sensitivity can come into play. I'm trying to find the links to back this up
        – Edward Comeau
        Aug 28 '15 at 9:30










        up vote
        0
        down vote













        All you have to do is to convert first the string to date.



        select * 
        from student
        where dob between convert(date, '20150820') and convert(date, '20150828')





        share|improve this answer


























          up vote
          0
          down vote













          All you have to do is to convert first the string to date.



          select * 
          from student
          where dob between convert(date, '20150820') and convert(date, '20150828')





          share|improve this answer
























            up vote
            0
            down vote










            up vote
            0
            down vote









            All you have to do is to convert first the string to date.



            select * 
            from student
            where dob between convert(date, '20150820') and convert(date, '20150828')





            share|improve this answer














            All you have to do is to convert first the string to date.



            select * 
            from student
            where dob between convert(date, '20150820') and convert(date, '20150828')






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Aug 28 '15 at 8:12









            marc_s

            566k12610921245




            566k12610921245










            answered Aug 28 '15 at 8:07









            kwingkwing.ko

            577315




            577315




















                up vote
                0
                down vote













                Why is this happening?



                The comparison is executed from left to right and the order of characters is determined by the codepage in use.




                Sort Order



                Sort order specifies the way that data values are sorted, affecting
                the results of data comparison. The sorting of data is accomplished
                through collations, and it can be optimized using indexes.




                https://msdn.microsoft.com/en-us/library/ms143726.aspx






                share|improve this answer
























                  up vote
                  0
                  down vote













                  Why is this happening?



                  The comparison is executed from left to right and the order of characters is determined by the codepage in use.




                  Sort Order



                  Sort order specifies the way that data values are sorted, affecting
                  the results of data comparison. The sorting of data is accomplished
                  through collations, and it can be optimized using indexes.




                  https://msdn.microsoft.com/en-us/library/ms143726.aspx






                  share|improve this answer






















                    up vote
                    0
                    down vote










                    up vote
                    0
                    down vote









                    Why is this happening?



                    The comparison is executed from left to right and the order of characters is determined by the codepage in use.




                    Sort Order



                    Sort order specifies the way that data values are sorted, affecting
                    the results of data comparison. The sorting of data is accomplished
                    through collations, and it can be optimized using indexes.




                    https://msdn.microsoft.com/en-us/library/ms143726.aspx






                    share|improve this answer












                    Why is this happening?



                    The comparison is executed from left to right and the order of characters is determined by the codepage in use.




                    Sort Order



                    Sort order specifies the way that data values are sorted, affecting
                    the results of data comparison. The sorting of data is accomplished
                    through collations, and it can be optimized using indexes.




                    https://msdn.microsoft.com/en-us/library/ms143726.aspx







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Aug 28 '15 at 9:34









                    Edward Comeau

                    1,7611521




                    1,7611521




















                        up vote
                        -2
                        down vote













                        There are problems with between in T-SQL.



                        But if you want a fast answer convert to date first and use >= <= or even datediff to compare - maybe write a between function yourself if you want the easy use like between and no care about begin and start times ...



                        • What do BETWEEN and the devil have in common?





                        share|improve this answer


























                          up vote
                          -2
                          down vote













                          There are problems with between in T-SQL.



                          But if you want a fast answer convert to date first and use >= <= or even datediff to compare - maybe write a between function yourself if you want the easy use like between and no care about begin and start times ...



                          • What do BETWEEN and the devil have in common?





                          share|improve this answer
























                            up vote
                            -2
                            down vote










                            up vote
                            -2
                            down vote









                            There are problems with between in T-SQL.



                            But if you want a fast answer convert to date first and use >= <= or even datediff to compare - maybe write a between function yourself if you want the easy use like between and no care about begin and start times ...



                            • What do BETWEEN and the devil have in common?





                            share|improve this answer














                            There are problems with between in T-SQL.



                            But if you want a fast answer convert to date first and use >= <= or even datediff to compare - maybe write a between function yourself if you want the easy use like between and no care about begin and start times ...



                            • What do BETWEEN and the devil have in common?






                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Nov 10 at 22:05









                            Aaron Bertrand

                            206k27358401




                            206k27358401










                            answered Aug 28 '15 at 7:51









                            Beinfreiheit

                            152




                            152



























                                 

                                draft saved


                                draft discarded















































                                 


                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function ()
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f32265817%2fstrange-behaviour-of-sql-query-with-between-operator%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







                                這個網誌中的熱門文章

                                What does pagestruct do in Eviews?

                                Dutch intervention in Lombok and Karangasem

                                Channel Islands