2016-12-19 4 views
1

Ich habe ein paar Tabellen einer Datenbank, wo man eine Menge von Matrizen definiert und die andere die Daten in den MatrizenFinden Element fehlt SQL

Matrices

Id Name 
1 M1 
2 M2 
3 M3 
4 M4 

Matrixelemente

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 

Also die Matrix_Id Spalte ist ein Fremdschlüssel zurück zu Id der Matrices Tabelle. Die ElementKey repräsentiert ein ij-Paar. Die Matrizen sind spärlich, also kann es ein Element mit einem bestimmten Schlüssel geben oder auch nicht. Wenn jedoch eine Matrix eine bestimmte ElementKey hat, muss die ElementKey mit dieser ID in ALLEN Matrizen definiert werden.

Gibt es einige SQL, die ich ausführen kann, die Matrix_Id und ElementKey Kombinationen für alle beleidigenden Einträge finden, d. H. Eine, die nicht für alle Matrizen definiert ist? Also für das obige Beispiel, ElementKey = 2 ist für Matrix 1, 2 und 4 aber nicht 3 definiert, so würde ich [Matrix = 3, ElementKey = 2] zurück erwarten.

Antwort

1

Dadurch werden die fehlenden Elemente erhalten und die Matrizen sie sind in:

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; 

Die cross join erzeugt alle Kombinationen von Matrizen mit bekannten Elementtasten. Die left join und where finden dann diejenigen, die fehlen.

0

Zuerst erstellen wir eine Liste aller Live-Elemente, dann Querverbindung zu allen aktiven Matrizen. Mit dieser Liste verlassen wir die aktiven Elemente und verwenden einen Fall, um festzustellen, ob sie existieren.

Ich habe ANSI verwendet, aber ein CTE wäre besser, wenn SQL Server oder Oracle.

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 
0

Dank den Antworten, die ich hatte. Ich konnte es nicht effektiv implementieren, da ich Entity Framework verwende und es schwierig ist, den angegebenen Code in eine Abfrageanweisung zu übersetzen, die mir die Ergebnisse zurückgibt. Ich habe mich von den gegebenen Proben inspirieren lassen und das ist es, was ich mir ausgedacht habe.

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)); 
    } 
}