Domanda

Ho una tabella con più colonne di date per dipendente:

   Emp 1, Date1, Date2, Date3
   Emp 2, Date1, Date2, Date3

ecc.

Vorrei scrivere una singola query che mi restituisca la data massima delle tre date disponibili per singolo dipendente. Capisco di dover scrivere una query UNION ALL ma non riesco a ottenere la sintassi in modo da ottenere un valore massimo per record di dipendente. Continuo a ottenere lo stesso valore per tutti i dipendenti. Sono sicuro che questo è un errore stupido, ma mi sta facendo impazzire. Qualsiasi aiuto sarebbe molto apprezzato.


Grazie per le risposte immediate! C'è un modo per farlo senza usare un'istruzione iif? Mi piacerebbe generalizzarlo, se possibile, dal momento che ci sono molti altri campi di date e diventa davvero ingombrante capire la logica IIF.

Inoltre, ho dimenticato di dire che una qualsiasi di quelle date potrebbe essere vuota e la logica IIF sembra restituire il valore NULL come valore massimo.

È stato utile?

Soluzione

Funzionerà qualcosa del genere?

select
  EmployeeColumn,
  iff(iif(Date1 > Date2, Date1, Date2) > Date3, iif(Date1 > Date2, Date1, Date2), Date3)
from yourTable

Altri suggerimenti

SELECT ID, Max(TheDate) AS MaxDate
FROM
(
   SELECT ID, Date1 AS TheDate
   FROM myTable
   UNION 
   SELECT ID, Date2 AS TheDate
   FROM myTable
   UNION
   SELECT ID, Date3 AS TheDate
   FROM myTable
)
GROUP BY ID

So che questa non è una soluzione pulita.
Ma questo è quello che stai cercando quando hai scritto UNION .

EDIT: puoi usare UNION ALL invece di UNION . Con la query sopra, suppongo che non farà differenza nell'output.

Farebbe qualcosa del genere: (questo era MSSQL2008 non sono sicuro che funzionerà in Acess)

Crea dati di prova

create table t1
    ( EmployeeId int,
      Date1  datetime,
      Date2  datetime,
      date3  datetime)

insert into t1 values (1, '2009-10-11', '2009-04-01', '2009-12-25')
insert into t1 values (2, '2009-10-24', '2009-04-03', '2009-12-19')

Le mie query

select case 
    when date1 > date2 and DATE1 > date3 then date1
    when date2 > date1 and date2 > date3 then date2
    when date3 > date1 and date3 > date2 then date3
    end as highest
    from t1 

Se non si desidera limitare la soluzione a SQL, è possibile utilizzare la mia funzione iMax ():

  Public Function iMax(ParamArray p()) As Variant
  ' Idea from Trevor Best in Usenet MessageID rib5dv45ko62adf2v0d1cot4kiu5t8mbdp@4ax.com
    Dim i As Long
    Dim lngUBound As Long
    Dim v As Variant

    v = p(LBound(p))
    lngUBound = UBound(p)
    For i = LBound(p) + 1 To lngUBound
      If v < p(i) Then
         v = p(i)
      End If
    Next
    iMax = v
  End Function

Lo chiamo " Max immediato () " per analogia da IIf (), Immediate If (), perché è destinato all'elaborazione a livello di riga all'interno di una query.

Wow! Sto vedendo che è troppo complesso per fare un semplice: Max (Field-Constant1, Constant2) .

Il mio obiettivo: calcolare un valore in base a un solo archiviato, ma non lasciare che il valore calcolato sia inferiore a una costante.

Espandi righe su una tabella a due campi (KeyField, ValueField):

1 10
2 5
3 8
4 Null

Voglio una selezione che ritorni (quando Constant1 = 6 e Constant2 = 1), ho messo l'intera matematica per chiarirla (solo la parte più in alto a destra dopo l'ultima = è ciò che voglio):

1 Max(10-6,1)=Max(4,1)=4
2 Max(5-6,1)=Max(-1,1)=1
3 Max(8-6,1)=Max(2,1)=1
4 Max(Null-6,1)=Max(Null,1)=Null

Quindi voglio solo (quando Constant1 = 6 e Constant2 = 1) nel caso in cui non sia abbastanza chiaro:

1 4
2 1
3 1
4 Null

Attenzione a quello Null.

Voglio davvero qualcosa di molto più complesso, ma risolvendo che sarei in grado di risolvere quello complesso che voglio.

Può essere ripreso come: -Ritorna Null se il valore è Null o non è un valore valido per l'operatore matematico utilizzato (non sempre è solo un - o un +, ecc.) -Ritorna il valore calcolato se è possibile eseguire la matematica, ma limitato a un intervallo (non meno di un valore e non più grande di un altro valore).

Se lo faccio su pseudo-codice sarebbe come questo:

try // try to do the maths
   MyCalculatedValue=SomeMaths(FieldValue);
   MyCalculatedValue=Min(Max(MyCalculatedValue,MinValue),MaxValue);
except // In case the SomeMaths can not be done (FieldValue is Null, negative square, division by zero, etc)
      MyCalculatedValue=Null;
end;
return MyCalculatedValue;

Nel caso in cui qualcuno dica che il database non è normalizzato: voglio fare alcuni calcoli in un campo, quindi limitare il risultato in un intervallo; il database di esempio più piccolo avrà solo una tabella che avrà solo due campi (campo chiave univoco, campo dati), che è impossibile non essere completamente normalizzati; non sto parlando del massimo di alcuni campi su una riga, né del massimo per una tabella completa su un campo (funzioni di aggregazione), voglio solo mettere un limite inferiore e uno superiore a un valore calcolato, ma considerando Null quando tale valore è Null o non è possibile eseguire la matematica con tale valore (casi come Constant1 / (FieldValue-Constant2), ecc.).

Campione reale nel caso in cui qualcuno non ottenga quando questo può essere usato:

Campi tabella:

ID (Key)
SpacePosition (DecimalData)

Campi dei risultati desiderati per la query:

ID as ID
Min(Max(SpacePosition-SomeSpaceLongitud,StartPosition),EndPosition) AS RangeStart
Min(Max(SpacePosition+SomeSpaceLongitud,StartPosition),EndPosition) AS RangeEnd

Spero che il campione sia chiaro e spero che qualcuno possa aiutarti, con qualcosa di più semplice dell'uso delle funzioni VBA!

P.D .: Pensa che tali matematiche siano più complesse di solo + e - e che la tabella abbia molti, molti più registri di pochi, pensa ad alcuni miliardi di registri. P.P.D .: Non è un'opzione per codificare tali risultati, poiché non sarebbe un database normalizzato e, peggio ancora, tali limiti di intervallo sono valori digitati dall'utente durante l'esecuzione della query.

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