Ripetendo righe da destra
-
02-01-2020 - |
Domanda
La mia applicazione consente di risparmiare registri che devono essere presi almeno una volta durante ciascuno dei 3 diversi periodi di tempo durante il giorno.Così idealmente 3 registri al giorno, ciascuno con un ID di tempo unico.Ho bisogno di scrivere un rapporto sulle eccezioni (MSSQL 2008) che mostrerà quando viene perso un periodo di tempo per un dato giorno.Ho una tabella LogimetPeriods che contiene 3 righe per ciascuno dei periodi di tempo.La tabella dei registri contiene LogTimePeriodID, quindi non è necessario eseguire alcuna logica per vedere quale periodo di tempo il registro appartiene (che viene fatto tramite l'applicazione).
So che ho bisogno di qualcosa sulla falsariga di un join destro / sinistro per provare ad abbinare tutto il logimeyPeriodID per ogni riga di registro per una data data.Non riesco a fare progressi.Qualsiasi aiuto è apprezzato!Grazie per la lettura.
Modifica: uscita desiderata sotto
Data |Logeriodid
.
6/3 |.3
6/5 |.2
.
6/5 |.3
Soluzione
Il tuo violino SQL è impostato per utilizzare MySQL, non SQL Server 2008, quindi non posso testare la mia risposta contro i tuoi dati: tuttavia, in base alla mia comprensione delle tue esigenze e supponendo che tu stia interrogando un database SQL 2008, quanto segueL'esempio dovrebbe funzionare per te (i riferimenti alle mie variabili da tavolo sarebbero ovviamente sostituiti con le tabelle effettive).
DECLARE @StartDate DATE = '06/04/2014'
DECLARE @EndDate DATE = GETDATE();
DECLARE @LogTimePeriod TABLE (LogTimePeriodID INT IDENTITY(1,1), TimePeriod VARCHAR(20))
INSERT INTO @LogTImePeriod (TimePeriod) SELECT '00:00 - 07:59'
INSERT INTO @LogTImePeriod (TimePeriod) SELECT '08:00 - 15:59'
INSERT INTO @LogTImePeriod (TimePeriod) SELECT '16:00 - 23:59'
DECLARE @logs TABLE (LogDataID INT IDENTITY(1,1), LogDate DATE, SomeInformation VARCHAR(10), LogTimePeriodID INT)
INSERT INTO @logs (SomeInformation, LogDate, LogTimePeriodID) SELECT 'abc', '6/4/2014', 1
INSERT INTO @logs (SomeInformation, LogDate, LogTimePeriodID) SELECT 'def', '6/4/2014', 2
INSERT INTO @logs (SomeInformation, LogDate, LogTimePeriodID) SELECT 'ghi', '6/4/2014', 3
INSERT INTO @logs (SomeInformation, LogDate, LogTimePeriodID) SELECT 'abc', '6/5/2014', 1
INSERT INTO @logs (SomeInformation, LogDate, LogTimePeriodID) SELECT 'def', '6/5/2014', 2;
WITH dates AS (
SELECT CAST(@StartDate AS DATETIME) 'date'
UNION ALL
SELECT DATEADD(dd, 1, t.date)
FROM dates t
WHERE DATEADD(dd, 1, t.date) <= @EndDate)
SELECT ltp.LogTimePeriodID, ltp.TimePeriod, dates.date
FROM
@LogTimePeriod ltp
INNER JOIN
dates ON 1=1
LEFT JOIN
@logs ld ON
ltp.LogTimePeriodID = ld.LogTimePeriodID AND
dates.date = ld.LogDate
WHERE ld.LogDataID IS NULL
OPTION (MAXRECURSION 1000) -- 0 is unlimited, 1000 limits to 1000 rows
. Altri suggerimenti
SQLServer 2008 ha la parola chiave EXCEPT
che sottrae il secondo recordset dal primo.
In questo caso è possibile generare tutti i registri possibili e rimuovere da quelli quelli nella tabella dei registri, che lascerà i registri non presenti nella tabella.
SELECT DISTINCT StartDateTime, StartTime, EndTime
FROM Logs
CROSS JOIN LogTimePeriods
EXCEPT
SELECT StartDateTime, StartTime, EndTime
FROM LogTimePeriods ltp
LEFT JOIN logs l ON l.LogTimePeriodID = ltp.LogTimePeriodID
ORDER BY StartDateTime, StartTime
.
sqlfiddle demo con i dati convertiti in SQLServer 2008