Azure ADF Eroare eroare Aritmetică preaplin expresie de conversie a datelor de tip int

0

Problema

Lucrez cu azure ADF și am probleme când am execute această interogare pe azure ADF:

SELECT COUNT(*) AS c
FROM TABLE 
WHERE CONVERT(date, (FORMAT(DATEADD(second, CONVERT(bigint, TS) / 1000, '19700101'), 'yyyy-MM-dd'))) = CONVERT(Date, GETDATE())

Rezultatul este o eroare

Aritmetică preaplin

dar dacă am schimba = la un >=, interogarea funcționează și returnează un rezultat.

La TS este un UNIXTIMESTAMP ca 1637680012264.

Folosind o combinație de >= și < nu este bine pentru că am de-a face cu nu învecinate zile (am nevoie pentru a utiliza WHERE TS IN (date1, date2, etc...)

Ar putea cineva sa ma ajute? Multumesc anticipat

azure azure-data-factory sql sql-server
2021-11-23 15:02:27
2

Cel mai bun răspuns

0

De preferință, mi-ar schimba tabelul de la magazin datetime2 valori în loc de complicate epoca nedorite.

Dar, presupunând că nu se poate repara design...

Pentru a Larnu punct, nu vreau să aplice calculele la coloană, și tu cu siguranță nu vreau să se aplice FORMAT() pentru ambele părți, deoarece FORMAT() este un câine absolut.

În schimb, mi-ar găsi limitele de astăzi, și de a folosi un deschise gama. Asta presupune TS coloana trebuie să fie bigint:

DECLARE @d date = GETDATE();

DECLARE @start bigint = DATEDIFF(SECOND, '19700101', @d),
        @end   bigint = DATEDIFF(SECOND, '19700101', DATEADD(DAY, 1, @d));

SELECT COUNT(*) AS c
FROM dbo.[TABLE]
WHERE TS >= @start * 1000 
  AND TS <  @end   * 1000;

Acest lucru evită orice formatare deasupra capului, complicate și inutile converti expresii (TS trebuie să fie deja un bigint, așa că de ce explicite CONVERT()?).


Dacă ai nevoie de non-contigue de date, ok, încă putem realiza acest lucru cu mult mai puțin abuz de masă. Doar a crea un #temp masă sau masă variabilă cu computerizata coloane, introduceți mai multe date într-acolo, și apoi exterior adere la ea.

DECLARE @d table
(
  d datetime2, 
  s AS CONVERT(bigint, 
    DATEDIFF(SECOND, '19700101', d)) * 1000,
  e AS CONVERT(bigint, 
    DATEDIFF(SECOND, '19700101', DATEADD(DAY, 1, d))) * 1000
);

INSERT @d(d) VALUES('20211123'),('20211007');

-- if you want a row per day:
SELECT d.d, COUNT(t.TS) AS c
FROM @d AS d
LEFT OUTER JOIN dbo.[TABLE] AS t
   ON  t.TS >= d.s
   AND t.TS <  d.e
GROUP BY d.d
ORDER BY d.d;

-- if you just want a total count:
SELECT COUNT(t.TS) AS c
FROM @d AS d
LEFT OUTER JOIN dbo.[TABLE] AS t
   ON  t.TS >= d.s
   AND t.TS <  d.e;

Mai multe pe data de obiceiurile proaste si cele mai bune practici:

2021-11-23 15:46:34

Multumesc Aaron, chiar dacă soluția nu este ceea ce am fost în căutarea pentru tine iluminate echipa mea cu "Asta nu e sursa de eroare. DATEADD nu este niciodată de gând să fie în măsură să adăugați 3 miliarde de secunde să 1970. Așa că poate împărți din nou și încercați să adăugați de minute, dacă vă pasă doar de data, al doilea nivel de precizie nu ar trebui să fie important. Puteți oferi câteva valori de probă pentru TS și rezultatele preconizate pentru cei". Deci convertit UNIXTIMESTAMP în ZILE de divinding pentru 60*60*1000*24
Salvatore Bonanno

@SalvatoreBonanno Dar asta e încă o extrem de ineficient mod de a rezolva problema. Vrei matematică pe de altă parte de clauza where, ai încredere în mine. Cu excepția cazului în care TS coloana nu este indexat și știi sigur că nu va mai indexa.
Aaron Bertrand

Da, am văzut-o soluție cu temp de masă. Cele mai problematice chestia este că eu pot avea doar acces de citire la masa ( masa este pe nor) deci, eu nu știu nimic despre index pe el (ar putea fi o imagine prea!) . Deci, problema de matematica a rezolvat problema pentru moment, dar voi încerca să optimizat cum ai spus.
Salvatore Bonanno
-1

Am repro-ar în ADF mediu și a fost capabil de a obține rezultate de succes.

Mai jos este o mostră de masă:

Aici, am 3 randuri cu data de '2021-11-23' și 2 rânduri de2021-11-24'. TS coloana are o întâlnire în UNIX timestamp format și dt_format coloana este de a arăta TS coloana în format dată.

enter image description here

ADF:

Folosind Lookup activitate, obtinerea de numărul de rânduri în care TS coloană are data de azi. (Eu sunt, folosind codul tău cu un alt tabel).

SELECT COUNT(*) AS c
FROM tb1 
WHERE CONVERT(date, (FORMAT(DATEADD(second, CONVERT(bigint, TS) / 1000, '19700101'), 'yyyy-MM-dd'))) = CONVERT(Date, GETDATE())

enter image description here

Ieșire:

enter image description here

2021-11-23 15:28:21

În alte limbi

Această pagină este în alte limbi

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................