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

SQL सर्वर में इस आउटपुट को कैसे क्वेरी करें

शुभ दिन,

कृपया जांचें कि क्या नीचे दिया गया समाधान आपकी सभी आवश्यकताओं को हल करता है। मैंने आपके डेटा और कुछ और पंक्तियों के साथ इसका परीक्षण किया, लेकिन फिर से जांचना हमेशा सर्वोत्तम होता है। पहली नज़र में ऐसा लगता है कि यह अनुरोधित परिणाम देता है। मैं बाद में कुछ स्पष्टीकरण जोड़ूंगा

मैं इस क्वेरी का उपयोग कर रहा हूं:

DECLARE @Date DATE = '2018-06-12';
with MyCTE as (
    SELECT 
        t.CustName,t.Country,t.RecordedTime,t.CurrNo, D = CONVERT(DATE, RecordedTime)
        ,RN_D = ROW_NUMBER() 
            OVER (partition by t.CustName order by t.CurrNo desc)
        ,RN = ROW_NUMBER() 
            OVER (partition by t.CustName order by t.CurrNo)
        ,RN_Old = ROW_NUMBER() 
            OVER (partition by t.CustName, (CASE WHEN CONVERT(DATE, RecordedTime) < @Date then 0 else 1 END) order by t.CurrNo desc)
        ,Cnt = COUNT(*) 
            OVER (partition by t.CustName)
        ,CntToday = COUNT(CASE WHEN CONVERT(DATE, RecordedTime) = @Date THEN 1 ELSE NULL END) 
            OVER (partition by t.CustName)
    FROM Test t
    where 
        -- returns rows untill current date
        CONVERT (DATE, RecordedTime) <= @Date 
        -- only if relevnat to current date
        and EXISTS (
            SELECT * FROM test t0 
            where CONVERT (DATE, RecordedTime) = @Date and t0.CustName = t.CustName
        )
)
,MyCTE2 as (
    select
        CustName, Country, RecordedTime, D, CurrNo, RN_D, RN, Cnt, t2.c, History, CntToday, RN_Old
    from MyCTE t1
    left JOIN (select * from (values(1, 'NEW'),(1, 'BEFORE')) t2(c, History) ) t2 
        on t1.CurrNo = t2.c
            and CntToday > 1
            and D = @Date
    where 
        RN_D = 1 
        or (RN = 1 and D = @Date) 
        or (RN_Old = 1 and D < @Date)
)
,MyCTE3 as (
    select CustName, Country, RecordedTime
        -- unmarke the bellow comment in order to get the accessories columns I used
        -- This is recommended to understand the line-of-thinking
        --, D, c, RN_D, RN, CurrNo, Cnt, CntToday, RN_Old
        , History = CASE
            WHEN CurrNo = 1 and Cnt = 1 then 'NEW'
            WHEN RN_D = 1 then 'CURRENT'
            else ISNULL(History,'BEFORE')
        END
    from MyCTE2
)
select CustName, Country, RecordedTime--, D, c, RN_D, RN, CurrNo, Cnt, CntToday, RN_Old
    ,Audit = CASE when History='New' then 'ADD' else 'CHANGE'  END
    , History
from MyCTE3

परीक्षण को आसान बनाने के लिए मैं पूरी क्वेरी को टेबल फ़ंक्शन में सम्मिलित करता हूं

DROP FUNCTION IF EXISTS dbo.F
GO
CREATE FUNCTION dbo.F(@Date DATE)
RETURNS TABLE AS RETURN (

--DECLARE @Date DATE = '2018-06-12';
with MyCTE as (
    SELECT 
        t.CustName,t.Country,t.RecordedTime,t.CurrNo, D = CONVERT(DATE, RecordedTime)
        ,RN_D = ROW_NUMBER() 
            OVER (partition by t.CustName order by t.CurrNo desc)
        ,RN = ROW_NUMBER() 
            OVER (partition by t.CustName order by t.CurrNo)
        ,RN_Old = ROW_NUMBER() 
            OVER (partition by t.CustName, (CASE WHEN CONVERT(DATE, RecordedTime) < @Date then 0 else 1 END) order by t.CurrNo desc)
        ,Cnt = COUNT(*) 
            OVER (partition by t.CustName)
        ,CntToday = COUNT(CASE WHEN CONVERT(DATE, RecordedTime) = @Date THEN 1 ELSE NULL END) 
            OVER (partition by t.CustName)
    FROM Test t
    where 
        -- returns rows untill current date
        CONVERT (DATE, RecordedTime) <= @Date 
        -- only if relevnat to current date
        and EXISTS (
            SELECT * FROM test t0 
            where CONVERT (DATE, RecordedTime) = @Date and t0.CustName = t.CustName
        )
)
,MyCTE2 as (
    select
        CustName, Country, RecordedTime, D, CurrNo, RN_D, RN, Cnt, t2.c, History, CntToday, RN_Old
    from MyCTE t1
    left JOIN (select * from (values(1, 'NEW'),(1, 'BEFORE')) t2(c, History) ) t2 
        on t1.CurrNo = t2.c
            and CntToday > 1
            and D = @Date
    where 
        RN_D = 1 
        or (RN = 1 and D = @Date) 
        or (RN_Old = 1 and D < @Date)
)
,MyCTE3 as (
    select CustName, Country, RecordedTime
        -- unmarke the bellow comment in order to get the accessories columns I used
        -- This is recommended to understand the line-of-thinking
        --, D, c, RN_D, RN, CurrNo, Cnt, CntToday, RN_Old
        , History = CASE
            WHEN CurrNo = 1 and Cnt = 1 then 'NEW'
            WHEN RN_D = 1 then 'CURRENT'
            else ISNULL(History,'BEFORE')
        END
    from MyCTE2
)
select CustName, Country, RecordedTime--, D, c, RN_D, RN, CurrNo, Cnt, CntToday, RN_Old
    ,Audit = CASE when History='New' then 'ADD' else 'CHANGE'  END
    , History
from MyCTE3
--order by CustName, RecordedTime
)
GO

फ़ंक्शन का उपयोग करना एकाधिक परीक्षण करना आसान बनाता है, लेकिन शायद उत्पादन में आप प्रत्यक्ष क्वेरी का उपयोग करना चाहेंगे

-- Test
select * from F('2018-06-01') order by CustName , RecordedTime
select * from F('2018-06-02') order by CustName , RecordedTime
select * from F('2018-06-03') order by CustName , RecordedTime
select * from F('2018-06-10') order by CustName , RecordedTime
select * from F('2018-06-11') order by CustName , RecordedTime
select * from F('2018-06-12') order by CustName , RecordedTime
select * from F('2018-06-13') order by CustName , RecordedTime
select * from F('2018-06-14') order by CustName , RecordedTime

/**************** 2018-08-19 14:05 इज़राइल समय पर अपडेट करें ****************/

मैंने देखा है कि थ्रेड में भाग लेने के लिए कुछ और जानकारी जोड़ना महत्वपूर्ण है। मुझे आशा है कि यह उपयोगी होगा

सबसे पहले, आइए तीन प्रश्नों की निष्पादन योजनाओं के अनुसार संसाधनों के उपयोग के प्रतिशत की तुलना करें:(1) मेरा समाधान, (2) पहला समाधान अद्यतन करने के बाद मौलिक कंसारा सेकंड समाधान, और (3) मौलिक कंसारा पहला समाधान

आइए अब मौलिक कंसारा सेकेंड सॉल्यूशन के EP की इमेज देखें:

यह क्वेरी तालिका को 11 बार स्कैन करती है!



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL सर्वर प्रबंधन स्टूडियो - TSQL कोडिंग प्रक्रिया में सुधार के लिए टिप्स

  2. SqlServerSpatial.dll लोड करने में असमर्थ

  3. SQL सर्वर मौजूदा तालिका में चुनें

  4. पहचान_इन्सर्ट का उपयोग करने के बाद स्वचालित रूप से कैसे शोध करें?

  5. SSMS में SQL सर्वर क्वेरी परिणाम में एक मान हाइपरलिंक करें