【问题标题】:Duplication employee in table due to switch in department由于部门切换导致表中重复员工
【发布时间】:2018-05-31 13:20:34
【问题描述】:

我有一个问题,我的公司有一个客户满意度计划,它从我们数据库系统的不同表中获取大量数据。

问题是我只想显示特定部门的客户满意度百分比,因此只显示该特定部门的员工。

问题出在我从中获取员工的表中,如果他们换了部门,则有相同员工的重复,所以如果他们一年前在一个部门工作,今天搬到另一个部门,它会告诉我两者都注册了相同的ID,即使他们换了部门,我们的SQL程序中的逻辑代码如下:

"KS_DRIFT.V_AGENT_ALLOCATION age ON " + (queryParams.JoinOnFirstAgent ? "FØRSTE_AGENT" : "SIDSTE_AGENT") + " = age.AGENT_INITIALS AND TRUNC(TIDSPUNKT) BETWEEN ALLOCATION_START AND ALLOCATION_END " +
                  "WHERE " + 
                      "TRUNC(TIDSPUNKT) BETWEEN " + OracleConversion.ToOracleDate(queryParams.Interval.Lower) + " AND " + OracleConversion.ToOracleDate(queryParams.Interval.Upper)

我不确定如何确保它仅根据此 sql 查询获取员工今天活跃的部门?我希望任何人都可以帮助我更接近解决方案。

编辑:

完成查询

var sql = "SELECT " + 
                      "SPØRGSMÅL_ID, " +
                      "KARAKTER, " +
                      "COUNT(*) AS COUNT " +
                  "FROM " + 
                      "KS_DRIFT.KT_KARAKTER kara " +
                  "LEFT JOIN " + 
                      "KS_DRIFT.KT_BESVARELSE besv ON kara.BESVARELSE_ID = besv.EKSTERN_ID AND kara.TYPE = besv.TYPE " +
                  "LEFT JOIN " +
                      "KS_DRIFT.V_AGENT_ALLOCATION age ON " + (queryParams.JoinOnFirstAgent ? "FØRSTE_AGENT" : "SIDSTE_AGENT") + " = age.AGENT_INITIALS AND TRUNC(TIDSPUNKT) BETWEEN ALLOCATION_START AND ALLOCATION_END " +
                  "WHERE " + 
                      "TRUNC(TIDSPUNKT) BETWEEN " + OracleConversion.ToOracleDate(queryParams.Interval.Lower) + " AND " + OracleConversion.ToOracleDate(queryParams.Interval.Upper) + " AND " +
                      "SPØRGSMÅL_ID = " + queryParams.QuestionId +
                      (!queryParams.IncludeCDNs.IsNullOrEmpty() ? "AND CDN IN (" + queryParams.IncludeCDNs.ToDelimitedString(", ") + ") " : "") +
                      (!queryParams.ExcludeCDNs.IsNullOrEmpty() ? "AND CDN NOT IN (" + queryParams.ExcludeCDNs.ToDelimitedString(", ") + ") " : "") +
                      (!queryParams.AgentIds.IsNullOrEmpty() ? " AND AGENT_ID IN (" + queryParams.AgentIds.ToDelimitedString(", ") + ") " : "") +
                      (!queryParams.TeamIds.IsNullOrEmpty() ? " AND TEAM_ID IN (" + queryParams.TeamIds.ToDelimitedString(", ") + ") " : "") +
                  "GROUP BY " +
                      "SPØRGSMÅL_ID, " +
                      "KARAKTER";

使用 Gerard 建议的查询时出现错误消息

ORA-00932: inconsistente datatyper: forventede DATE, fik NUMBER ved Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode,OracleConnection conn,IntPtr opsErrCtx,OpoSqlValCtx* pOpoSqlValCtx,对象 src,字符串过程,布尔 bCheck) ved Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, String procedure, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, Boolean bCheck) ved Oracle.DataAccess.Client.OracleCommand.ExecuteReader(布尔重新查询,布尔填充请求,CommandBehavior 行为) ved Oracle.DataAccess.Client.OracleCommand.ExecuteReader()

ved NDDataProvider.Database.Oracle.Connection.DBConnection.ExecuteQuery(String query) i S:\s0book\ND Udviklings Dokumentation\Git Repository dump - THOMAS HER\NDSolution\DOPe Data Provider\Database\Oracle\Connection\DBConnection。 cs:林杰 456

OracleConversion.cs

    public class OracleConversion {

    public static string ToOracleValue(object value) {
        if (value == null)
            return "null";

        if (value is string)
            return OracleConversion.ToOracleString((String)value);

        if (value is Enum)
            return OracleConversion.ToOracleInteger((int)value);

        int integerValue;

        if (Int32.TryParse(value.ToString(), out integerValue))
            return OracleConversion.ToOracleInteger(integerValue);

        decimal decimalValue;

        if (Decimal.TryParse(value.ToString(), out decimalValue))
            return OracleConversion.ToOracleDecimal(decimalValue);

        if (value is Boolean)
            return OracleConversion.ToOracleBoolean((Boolean)value);

        if (value is DateTime)
            return OracleConversion.ToOracleDateTime((DateTime)value);

        if (value is NDUtilities.Time)
            return OracleConversion.ToOracleInteger(((NDUtilities.Time)value).SecondsOfDay);

        if (value is SolutionsEntity)
            return OracleConversion.ToOracleInteger(((SolutionsEntity)value).Id);

        return OracleConversion.ToOracleString(value.ToString());
    }

    public static string ToOracleBoolean(Nullable<bool> booleanValue) {
        string returnValue;

        if (booleanValue == null)
            returnValue = "null";
        else
            returnValue = (booleanValue.Value) ? "1" : "0";

        return returnValue;
    }

    public static string ToOracleInteger(Nullable<int> integerValue) {
        string returnValue;

        if (integerValue == null)
            returnValue = "null";
        else
            returnValue = integerValue.ToString();

        return returnValue;
    }

    public static string ToOracleDecimal(Nullable<decimal> decimalValue) {
        string returnValue;

        if (decimalValue == null)
            returnValue = "null";
        else
            returnValue = decimalValue.Value.ToString().Replace(",", ".");

        return returnValue;
    }

    public static string ToOracleString(string stringValue) {
        string returnValue;

        if (stringValue == null)
            returnValue = "null";
        else {
            returnValue = stringValue.Replace("'", "''");

            returnValue = "'" + returnValue + "'";
        }

        return returnValue;
    }

    public static string ToOracleDate(DateTime? dateTimeValue) {
        string returnValue;

        if (dateTimeValue == null)
            returnValue = "null";
        else
            returnValue = OracleConversion.ToOracleString(dateTimeValue.Value.ToString("yyyy-MM-dd"));

        return returnValue;
    }

    public static string ToOracleDateTime(DateTime? dateTimeValue) {
        string returnValue;

        if (dateTimeValue == null)
            returnValue = "null";
        else
            returnValue = "TO_DATE(" + OracleConversion.ToOracleString(dateTimeValue.Value.ToString("yyyy-MM-dd HH:mm:ss")) + ", " + OracleConversion.ToOracleString("yyyy-mm-dd hh24:mi:ss") + ")";

        return returnValue;
    }
}

}

【问题讨论】:

  • 请在包含该信息的表格中分享一些示例数据。在不知道您的数据的情况下,很难说出您将如何正确查询它以获取当前员工部门关系。
  • 表中是否有代表活动部门的列?如果没有,您可能需要按最大日期字段进行过滤。 TIDSPUNKT 代表什么?
  • 数据库表中的一个示例是 ALLOCATION_START,在一个示例中,员工从 2014-05-01 开始在一个部门,ALLOCATION_ENDED 2014-12-31,然后 ALLOCATION_START 2015-01-01 和ALLOCATION_ENDED 2100-0101,如何只选择最新的allocation_start?
  • 我没有任何代表活动部门的表,关于他们当前部门的唯一相关信息是 ALLOCATION_START 和 ALLOCATION_END
  • 如果你关心性能,不要“trunc(tidspunkt)”,而是使用“where tidspunkt >= low_date and tidspunkt

标签: sql oracle oracle11g


【解决方案1】:

只需在 sysdate 和分配列上添加一个测试

var sql = "SELECT " +
                  "SPØRGSMÅL_ID, " +
                  "KARAKTER, " +
                  "COUNT(*) AS COUNT " +
              "FROM " + 
                  "KS_DRIFT.KT_KARAKTER kara " +
              "LEFT JOIN " + 
                  "KS_DRIFT.KT_BESVARELSE besv ON kara.BESVARELSE_ID = besv.EKSTERN_ID AND kara.TYPE = besv.TYPE " +
              "LEFT JOIN " +
                  "KS_DRIFT.V_AGENT_ALLOCATION age ON " + (queryParams.JoinOnFirstAgent ? "FØRSTE_AGENT" : "SIDSTE_AGENT") + " = age.AGENT_INITIALS AND TIDSPUNKT >= ALLOCATION_START AND TIDSPUNKT < ALLOCATION_END + 1  " +
                  "and sysdate BETWEEN ALLOCATION_START AND ALLOCATION_END " +
              "WHERE TIDSPUNKT >= to_date(" +
                  OracleConversion.ToOracleDate(queryParams.Interval.Lower) +
                  ",'YYYY-MM-DD') AND TIDSPUNKT < to_date(" +
                  OracleConversion.ToOracleDate(queryParams.Interval.Upper) +
                  ",'YYYY-MM-DD') + 1 AND " +
                  "SPØRGSMÅL_ID = " + queryParams.QuestionId +
                  (!queryParams.IncludeCDNs.IsNullOrEmpty() ? "AND CDN IN (" + queryParams.IncludeCDNs.ToDelimitedString(", ") + ") " : "") +
                  (!queryParams.ExcludeCDNs.IsNullOrEmpty() ? "AND CDN NOT IN (" + queryParams.ExcludeCDNs.ToDelimitedString(", ") + ") " : "") +
                  (!queryParams.AgentIds.IsNullOrEmpty() ? " AND AGENT_ID IN (" + queryParams.AgentIds.ToDelimitedString(", ") + ") " : "") +
                  (!queryParams.TeamIds.IsNullOrEmpty() ? " AND TEAM_ID IN (" + queryParams.TeamIds.ToDelimitedString(", ") + ") " : "") +
              "GROUP BY " +
                  "SPØRGSMÅL_ID, " +
                  "KARAKTER";

【讨论】:

  • 我不确定您希望在上述代码中的哪个位置对 sysdate 进行此测试?你的意思是不是 "TRUNC(TIDSPUNKT) BETWEEN " + OracleConversion.ToOracleDate(queryParams.Interval.Lower) + " AND " + OracleConversion.ToOracleDate(queryParams.Interval.Upper) "?
  • 我说要“添加”它(加入),而不是“代替”。例如。在“哪里”之前。给我们完整的查询,我会把它放在正确的地方。
  • 我在原始问题的编辑中添加了完整的查询,因为它太长了,无法发表评论
  • @kwesi1337:您的查询似乎已经在考虑这一点。它正在选择在 TIDSPUNKT 日期为该部门工作的员工。不过,我不知道您为什么要使用外连接。并且一些 where 子句条件似乎将它们变成了内部连接,但我不能确定,因为不幸的是,您查询中的许多列都没有表限定符(所以我们不知道 TIDSPUNKT、CDN 等驻留在哪里) .你应该解决这个问题。
  • @kwesi1337:不。如果你不明白,找懂的人。不要试图猜测修复。
猜你喜欢
  • 2021-03-09
  • 1970-01-01
  • 2021-05-15
  • 2014-01-10
  • 1970-01-01
  • 2012-01-10
  • 1970-01-01
  • 2022-12-19
  • 2021-09-09
相关资源
最近更新 更多