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.

SQL Fiddle

Modifica: uscita desiderata sotto

Data |Logeriodid
. 6/3 |.3
6/5 |.2
. 6/5 |.3

È stato utile?

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top