简体   繁体   English

C#,建立SQL以选择给定年龄范围的用户

[英]c#, build sql to select a user given an age range

I have a talent table holding all my users with a column holding their birthdays. 我有一个人才表,其中包含所有用户,其中有一个列其生日的列。 what would be the best way Talent within a specified age range. 在指定年龄段内才能的最佳方式是什么? Here's what I have, but is seems to be off by a couple days. 这是我所拥有的,但似乎要过几天。 is there a better way? 有没有更好的办法?

// BUILD SQL FROM FORM DATA
sqlString += "SELECT * from Talent";

if (minAge != 0 || maxAge != 120)
{
     // The age criteria has been change, filter by age.

     // select all talents that have birthdays between the following 2 dates.
     DateTime startDate = (DateTime.Now - new TimeSpan((maxAge * 365), 0, 0, 0));  // maxAge * 365 = totalDays
     DateTime endDate = (DateTime.Now - new TimeSpan((minAge * 365), 0, 0, 0));
     sqlString += " WHERE Birthdate BETWEEN '" + startDate.ToString() + "' AND '" + endDate.ToString() + "'";
}

Assuming you're using SQL Server... 假设您正在使用SQL Server ...

using (var connection = new SqlConnection(connString))
    using (var command = connection.CreateCommand()) {

        string tsql = @"
            select *
                from Talent
                where DATEDIFF(YEAR, BirthDay, GETDATE()) BETWEEN @minAge AND @maxAge";

        command.CommandText = tsql;
        command.CommandType = CommandType.Text;

        int minAge = 1;
        int maxAge = 120;

        SqlParameter minAgeParam = command.CreateParameter();
        minAgeParam.Direction = ParameterDirection.Input;
        minAgeParam.DbType = SqlDbType.TinyInt;
        minAgeParam.ParameterName = "@minAge";
        minAgeParam.Value = minAge;

        SqlParameter maxAgeParam = command.CreateParameter();
        maxAgeParam.Direction = ParameterDirection.Input;
        maxAgeParam.DbType = SqlDbType.TinyInt;
        maxAgeParam.ParameterName = "@maxAge";
        maxAgeParam.Value = maxAge;

        // Just unsure here whether I must add the parameters to the command,
        // or if they are already part of it since I used the 
        // SqlCommand.CreateParameter() method. 
        // Been too long since I haven't done any ADO.NET
        command.Parameters.Add(minAgeParam);
        command.Parameters.Add(maxAgeParam);

        connection.Open();

        SqlDataReader reader = null;

        try {
            reader = command.ExecuteReader();
            // Process your records here...
        } finally {
            connection.Close()
            command.Dispose();
            connection.Dispose();
            if (reader != null) {
                reader.Dispose();
            }
        }
    }

Where @minAge and @maxAge are your age parameters. 其中@minAge@maxAge是您的年龄参数。

You may also tell the DATEDIFF TSQL function to consider the difference in days, in month, in hours, in minutes, in seconds, etc. Hence, you will have to convert your parameters value accordingly. 您还可以告诉DATEDIFF TSQL函数考虑天,月,小时,分钟,秒等的差异。因此,您将必须相应地转换参数值。

Personally, I've found using startDate.ToString("yy-MM-dd 00:00:00.000") and endDate.ToString("yy-MM-dd 23:59:59.000") works best (note the ,000 on the end date range. For some reason, in my experience, sql is off (probably due to some kind of rounding error) when it comes to ranges. 就个人而言,我发现使用startDate.ToString("yy-MM-dd 00:00:00.000")endDate.ToString("yy-MM-dd 23:59:59.000")效果最佳(请注意,出于某种原因,以我的经验,当涉及到范围时,sql已关闭(可能是由于某种舍入错误所致)。

As an aside, you can use static methods from the TimeSpan object for time calculations. TimeSpan ,您可以使用TimeSpan对象中的静态方法进行时间计算。 eg TimeSpan.FromDays(...) 例如TimeSpan.FromDays(...)

The problem might be related to DateTime.Now , which considers time as well as date. 问题可能与DateTime.Now有关,后者考虑了时间和日期。 Try replacing it with a DateTime.Today . 尝试将其替换为DateTime.Today

Why don't you use DateTime.AddYears method. 为什么不使用DateTime.AddYears方法。

DateTime startDate = DateTime.Now.AddYears(-maxAge);

insated of

DateTime startDate = (DateTime.Now - new TimeSpan((maxAge * 365), 0, 0, 0)); 

Another thing is: Please don't use + operator between strings to build a sql query, use StringBuilder instead. 另一件事是:请不要在字符串之间使用+运算符来构建sql查询,而应使用StringBuilder

物有所值-您的原始解决方案将用几天的时间,因为它使用365而不是计算leap年。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM