查找缺少的元素SQL

时间:2016-12-19 14:33:48

标签: sql matrix

我有几个数据库表,其中一个定义了一组矩阵,另一个定义了矩阵中的数据

矩阵

Id  Name
1   M1
2   M2
3   M3
4   M4

MatrixElements

Matrix_Id   ElementKey  Value
1           1           234
1           2           234
1           3           4432
2           1           234
2           2           13
2           3           123
3           1           34
3           3           345
4           1           234
4           2           11
4           3           344

因此Matrix_Id列是返回Id表的Matrices的外键。 ElementKey代表一对ij。矩阵是稀疏的,因此可能存在或不存在具有特定键的元素。但是,如果一个矩阵具有特定ElementKey,则必须在所有矩阵中定义具有该ID的ElementKey

我是否可以运行一些SQL,它会为任何有问题的条目找到Matrix_IdElementKey组合,即没有为所有矩阵定义的组合?因此,对于上面的示例,{1}} = 2是为Matrix 1,2和4而不是3定义的,所以我希望ElementKey回来。

3 个答案:

答案 0 :(得分:1)

这将获得缺少的元素及其所在的矩阵:

select m.id, me.element_key
from matrices m cross join
     (select distinct element_key from matrix_elements me) e left join
     matrix_elements me
     on me.matrix_id = m.id and me.element_key = e.element_key
where me.matrix_id is null;

cross join生成具有已知元素键的矩阵的所有组合。然后left joinwhere找到丢失的内容。

答案 1 :(得分:0)

首先,我们列出所有实时元素,然后交叉连接到所有活动矩阵。使用此列表,我们将连接活动元素并使用案例来确定它们是否存在。

我使用过ANSI,但如果是SQL服务器或Oracle,CTE会更好。

select c.id, c.ElementKey, case when b.MatrixID is null then 0 else 1 end as InPlace
from
  (
  select id, a.ElementKey
  from Matrices
  cross join
    (
    select distinct ElementKey
    from MatrixElements
    ) a
  ) c
left join Matrices b
on b.Matrix_id = c.id
and b.ElementKey = c.ElementKey

答案 2 :(得分:0)

感谢我的回应。我无法有效地实现它,因为我正在使用实体框架,并且很难将给定的代码转换为将返回结果的查询语句。我确实从给出的样本中获取灵感,这就是我想出来的。

public class Matrix
{
    [Key]
    public int Id { get; set; }
    public virtual List<MatrixElement> Data { get; set; }
}

public class MatrixElement
{
    [Key]
    public int Id { get; set; }
    public int OdPairKey { get; set; }
    public double Value { get; set; }
}

public class EngineDataContext : DbContext
{
    public virtual DbSet<Matrix> MatrixFiles { get; set; }
    public virtual DbSet<MatrixElement> MatrixData { get; set; }
}

public class SqliteRepository
{
    private readonly EngineDataContext _dataContext;

    public SqliteRepository(EngineDataContext dataContext)
    {
        _dataContext = dataContext;
    }

    public IEnumerable<Tuple<Matrix, int>> FindMissingODPairs(IEnumerable<Matrix> matrices)
    {
        IEnumerable<Matrix> matricesWithData =
            matrices.Select(m => _dataContext.MatrixFiles
            .Include("Data").First(mf => mf.Id == m.Id));

        // Do the cross join on matrices and OD pairs
        IEnumerable<dynamic> combinations =
            from m in matrices
            from od in matricesWithData.SelectMany(mat => mat.Data.Select(md => md.OdPairKey)).Distinct()
            select new { M = m.Id, O = od };

        // Find all the used matrix / OD pair combinations
        IEnumerable<dynamic> used =
            from m in matricesWithData
            from od in m.Data
            select new { M = m.Id, O = od.OdPairKey };

        // Find the missing combinations with a simple "Except" query
        return combinations
            .Except(used)
            .Select(c => new Tuple<Matrix, int>(matrices.First(m => m.Id == c.M), c.O));
    }
}