habe ich eine Tabelle, die die Geschichte der Änderungen an einem Produkt speichert und wollen eine Liste der Datensätze zu erhalten, die eine Änderung in Col1 oder Col2 oder Col3 haben, aber mich nicht Aufzeichnungen zeigen, dass ein nicht haben Änderung in einer dieser drei Spalten.Linq Filter Reihe Unterschiede in historischen
Hier ist ein Beispiel in SQL gemacht. Wie geht es dir mit Linq?
zum Testen temporäre Tabelle erstellen
CREATE TABLE #ProductHistorical(
IdProductHistorical int IDENTITY(1,1) NOT NULL,
IdProduct int NOT NULL,
DateChange datetime NULL,
Col1 int NOT NULL,
Col2 int NOT NULL,
Col3 int NOT NULL,
CONSTRAINT PK_ProductHistorical PRIMARY KEY CLUSTERED (IdProductHistorical ASC))
GO
Insert Testdaten
INSERT #ProductHistorical (IdProduct, DateChange, Col1, Col2, Col3) VALUES (1, CAST(0x0000A13900000000 AS DateTime), 1, 2, 3)
INSERT #ProductHistorical (IdProduct, DateChange, Col1, Col2, Col3) VALUES (1, CAST(0x0000A13A00000000 AS DateTime), 1, 2, 3)
INSERT #ProductHistorical (IdProduct, DateChange, Col1, Col2, Col3) VALUES (1, CAST(0x0000A13B00000000 AS DateTime), 1, 2, 3)
INSERT #ProductHistorical (IdProduct, DateChange, Col1, Col2, Col3) VALUES (1, CAST(0x0000A13C00000000 AS DateTime), 1, 1, 3)
INSERT #ProductHistorical (IdProduct, DateChange, Col1, Col2, Col3) VALUES (1, CAST(0x0000A13D00000000 AS DateTime), 1, 1, 3)
INSERT #ProductHistorical (IdProduct, DateChange, Col1, Col2, Col3) VALUES (1, CAST(0x0000A13E00000000 AS DateTime), 2, 2, 2)
INSERT #ProductHistorical (IdProduct, DateChange, Col1, Col2, Col3) VALUES (1, CAST(0x0000A13F00000000 AS DateTime), 2, 2, 2)
INSERT #ProductHistorical (IdProduct, DateChange, Col1, Col2, Col3) VALUES (1, CAST(0x0000A14000000000 AS DateTime), 2, 2, 2)
INSERT #ProductHistorical (IdProduct, DateChange, Col1, Col2, Col3) VALUES (1, CAST(0x0000A14100000000 AS DateTime), 1, 2, 3)
INSERT #ProductHistorical (IdProduct, DateChange, Col1, Col2, Col3) VALUES (2, CAST(0x0000A14200000000 AS DateTime), 1, 1, 1)
INSERT #ProductHistorical (IdProduct, DateChange, Col1, Col2, Col3) VALUES (2, CAST(0x0000A14300000000 AS DateTime), 1, 1, 2)
SQL Query
SELECT phWithChanges.DateChange,
phWithChanges.Col1,
phWithChanges.Col2,
phWithChanges.Col3
FROM #ProductHistorical ph
CROSS APPLY (
SELECT TOP 1 *
FROM #ProductHistorical phPost
WHERE phPost.IdProduct=ph.IdProduct AND
phPost.IdProductHistorical>ph.IdProductHistorical AND
(phPost.Col1<>ph.Col1 OR phPost.Col2<>ph.Col2 OR phPost.Col2<>ph.Col2)
ORDER BY phPost.IdProductHistorical ASC) phWithChanges
WHERE ph.IdProduct=1
GROUP BY phWithChanges.DateChange,phWithChanges.Col1,phWithChanges.Col2,phWithChanges.Col3
UNION
--Add First Row
SELECT * FROM
(SELECT TOP 1
phFirst.DateChange,
phFirst.Col1,
phFirst.Col2,
phFirst.Col3
FROM #ProductHistorical phFirst
WHERE phFirst.IdProduct=1 ORDER BY phFirst.IdProductHistorical) rowFirst
ORDER BY 1
Daten
IdProductHistorical IdProduct DateChange Col1 Col2 Col3
------------------- ----------- ----------------------- ----------- ----------- -----------
1 1 2013-01-01 00:00:00.000 1 2 3
2 1 2013-01-02 00:00:00.000 1 2 3
3 1 2013-01-03 00:00:00.000 1 2 3
4 1 2013-01-04 00:00:00.000 1 1 3
5 1 2013-01-05 00:00:00.000 1 1 3
6 1 2013-01-06 00:00:00.000 2 2 2
7 1 2013-01-07 00:00:00.000 2 2 2
8 1 2013-01-08 00:00:00.000 2 2 2
9 1 2013-01-09 00:00:00.000 1 2 3
10 2 2013-01-10 00:00:00.000 1 1 1
11 2 2013-01-11 00:00:00.000 1 1 2
Ergebnis
DateChange Col1 Col2 Col3
----------------------- ----------- ----------- -----------
2013-01-01 00:00:00.000 1 2 3
2013-01-04 00:00:00.000 1 1 3
2013-01-06 00:00:00.000 2 2 2
2013-01-09 00:00:00.000 1 2 3
Wie geht es Ihnen mit Linq?
Erster Ansatz
var query=(
from ph in ProductHistorical.Where(p=>p.IdProduct==1)
orderby ph.DateChange ascending
select new ProductHistoricalItem
{
DateChange = ph.DataChange,
Col1 = ph.Col1,
Col2 = ph.Col2,
Col3 = ph.Col3
});
List<ProductHistoricalItem> listResult=new List<ProductHistoricalItem>();
ProductHistoricalItem previous = null;
foreach (ProductHistoricalItem item in query)
{
if (previous == null ||
previous.Col1 != item.Col1 ||
previous.Col2 != item.Col2 ||
previous.Col3 != item.Col3)
{
listResult.Add(item);
previous = item;
}
}
Dies ist nicht sehr effizient. Wie kann ich es tun, ohne eine Schleife zu benutzen?
+1 für die Erstellung der Tabelle erstellen und fügt Anweisungen. –