Oracle
 sql >> डेटाबेस >  >> RDS >> Oracle

Oracle SQL दिनांक से लंबा और इसके विपरीत

आप अपने रूपांतरण में बहुत अधिक सटीकता खो रहे हैं ताकि दूसरे रास्ते पर वापस जा सकें। आप तिथियों के बजाय टाइमस्टैम्प का उपयोग करके करीब आ सकते हैं।

सबसे पहले आपकी प्रारंभिक क्वेरी समय घटक को पूरी तरह खो रही थी:

select to_char(date '1970-01-01'
  + (1432550197431912935 - power(2, 60))/power(2, 44), 'YYYY-MM-DD HH24:MI:SS')
from dual;

2013-07-09 01:13:19

... लेकिन उसके साथ भी, वापस परिवर्तित करना बहुत अधिक खो गया है:

select ((to_date('2013-07-09 01:13:19','YYYY-MM-DD HH24:MI:SS')
  - date '1970-01-01') * power(2, 44)) + power(2, 60) from dual;

1432550197477589405

जो आपको मिले 1432549301782839296 से करीब है, लेकिन अभी भी काफी दूर है।

समस्या का एक हिस्सा DATE . की सटीकता है , जो केवल दूसरे के लिए है। अगर आप TIMESTAMP का इस्तेमाल करते हैं इसके बजाय आप काफी करीब आ सकते हैं; आप देख सकते हैं कि होने वाला मान बहुत सटीक माना जाता है:

select timestamp '1970-01-01 00:00:00'
  + numtodsinterval((1432550197431912935 - power(2, 60))/power(2, 44), 'DAY')
from dual;

2013-07-09 01:13:18.775670462

उस बैक को परिवर्तित करना टाइमस्टैम्प अंकगणित द्वारा अंतराल परिणाम देने से जटिल है, जिसे बाद में आपको किसी संख्या पर वापस जाने के लिए हेरफेर करना होगा, पहले दिनों की मूल संख्या के रूप में:

select extract(day from int_val)
  + extract(hour from int_val) / 24
  + extract(minute from int_val) / (24 * 60)
  + extract(second from int_val) / (24 * 60 * 60)
from (
select to_timestamp('2013-07-09 01.13.18.775670462', 'YYYY-MM-DD HH24:MI:SS.FF9')
  - timestamp '1970-01-01 00:00:00' as int_val from dual);

15895.0509117554451620370370370370370371

... और फिर अपनी शक्ति में हेरफेर के साथ:

select ((extract(day from int_val)
    + extract(hour from int_val) / 24
    + extract(minute from int_val) / (24 * 60)
    + extract(second from int_val) / (24 * 60 * 60))
  * power(2, 44)) + power(2, 60)
as x
from (
select to_timestamp('2013-07-09 01.13.18.775670462', 'YYYY-MM-DD HH24:MI:SS.FF9')
  - timestamp '1970-01-01 00:00:00' as int_val from dual);

1432550197431912935.09988554676148148148

जो काफी करीब है। आप उसे निकटतम पूर्ण संख्या में छोटा या गोल कर सकते हैं।

बस अपने नंबरों और पावर मैनिपुलेशन को हर तरह से देखने से पता चलता है कि ऐसा लगता है कि ओरेकल सटीक रूप से सामना कर सकता है:

select (1432550197431912935 - power(2, 60)) / power(2, 44)
from dual;

15895.050911755445156359201064333319664

select (15895.050911755445156359201064333319664 * power(2, 44)) + power(2, 60)
from dual;

1432550197431912935.000...

टाइमस्टैम्प के साथ भी, आप उसमें से कुछ खो देते हैं, क्योंकि पहला मान 9-अंकीय भिन्नात्मक दूसरी सीमा से आगे जा रहा है। वह भाग जो भिन्नात्मक सेकंड का प्रतिनिधित्व करता है - एक बार जब आप 15895 घंटे आदि के लिए जिम्मेदार हो जाते हैं - .0000089776673785814232865555418862 है एक दिन का, जो .77567046150943497195839881896768 है सेकंड; टाइमस्टैम्प उस पर .775670462 . को गोल कर रहा है . तो यह कभी भी पूर्ण नहीं होगा।

इससे यह भी आश्चर्य होता है कि मूल संख्या कैसे उत्पन्न की जा रही है; ऐसा लगता है कि यह वास्तव में उस चरम सटीकता के समय का प्रतिनिधित्व नहीं करता है, क्योंकि यह yoctoseconds . यह वास्तव में स्पष्ट नहीं है कि क्या 'सटीक' वास्तव में 2 की शक्तियों के आधार पर हेरफेर किया जा रहा है, लेकिन यह वैसे भी बहुत उपयोगी नहीं दिखता है। यूनिक्स-शैली युग की तारीख का उपयोग करना, सेकंड या कभी-कभी मिलीसेकंड की गणना करना उस युग की तारीख के बाद से उपयोग करना अधिक आम है, अगर इसे किसी संख्या के रूप में संग्रहीत किया जाना है। यह डिज़ाइन... दिलचस्प है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. रेफरी कर्सर से पीएल/एसक्यूएल में अस्थायी तालिका में डेटा डालने के लिए थोक कैसे करें?

  2. हाइबरनेट में आईडी उत्पन्न करने के लिए मौजूदा Oracle अनुक्रम का उपयोग कैसे करें?

  3. एकाधिक IN पैरामीटर के साथ संग्रहीत प्रक्रिया

  4. ओरेकल आईआईएफ स्टेटमेंट

  5. Oracle में महीने का अंतिम दिन कैसे प्राप्त करें?