मैं वापस लौटता हूं और इस प्रश्न और उत्तर पर लौटता हूं। दुर्भाग्यवश कई स्थितियां हैं जब "रैंकिंग के लिए विंडो फ़ंक्शन" का उपयोग करके माइग्रेशन बहुत जटिल हो जाता है। उन स्थितियों हैं:
- कई-रखें DENSE_RANK विभिन्न आदेशों के आधार पर ओरेकल क्वेरी के चुनिंदा हिस्से में निर्माण ग्रुपिंग के सेट/रोलअप्स द्वारा
- समूहीकरण
इसलिए मैं इस सवाल का जवाब अतिरिक्त करने के लिए जोड़ देगा जानकारी। मूल डेटा SQLFIDDLE: http://sqlfiddle.com/#!6/e5c6d/6
1. पढ़ना ओरेकल समारोह:
select max(m.id), m.someId keep (DENSE_RANK FIRST ORDER BY m.UpdateDate desc)
from MyTable m
groupBy m.someId
वहाँ हम समूह में m.id की अधिकतम का चयन करें (someId, अद्यतन किया) जहां अद्यतन किया सबसे बड़ी यह समूह (someId है)
2. सीधे आगे रास्ता त्रुटि के कारण काम नहीं करता: स्तंभ 'MyTable.UpdateDate' का चयन में अमान्य है सूची क्योंकि यह या तो कुल कार्य या ग्रुप बाय क्लॉज में निहित नहीं है।
SELECT FIRST_VALUE(id) OVER(PARTITION BY someId ORDER BY UpdateDate DESC, id DESC) first_in_orderedset , someId
FROM MyTable
GROUP BY someId
3. improoved 'सीधे आगे' noneffective
SELECT someId, MIN(first_in_orderedset)
FROM
(SELECT FIRST_VALUE(id) OVER(PARTITION BY someId ORDER BY UpdateDate DESC, id DESC) first_in_orderedset , someId
FROM MyTable) t
GROUP BY someId;
4 है। पार लागू होते हैं: ऑरेकल:: http://sqlfiddle.com/#!4/c943c/23 एसक्यूएल सर्वर:
SELECT grouped.someId, orderedSet.FirstUpdateDate, maxInSet.first_in_orderedset FROM
(
SELECT mt.someId
FROM MyTable mt
GROUP BY mt.someId
) grouped CROSS APPLY
(
SELECT top 1 mt2.UpdateDate as FirstUpdateDate
FROM MyTable mt2
WHERE mt2.someId=grouped.someId
ORDER BY UpdateDate desc
) orderedSet CROSS APPLY
(
SELECT max(mt3.id) as first_in_orderedset
FROM MyTable mt3
WHERE mt3.someId=grouped.someId and mt3.UpdateDate=orderedSet.FirstUpdateDate
) maxInSet;
5. अब और अधिक जटिल तालिका मिलता है और अधिक जटिल क्वेरी की सुविधा देता है http://sqlfiddle.com/#!6/dc7fb/1/0 (डेटा pregenerated है और यह दोनों सैंडबॉक्स में एक ही है -
CREATE TABLE AlarmReports (
id int PRIMARY KEY,
clientId int, businessAreaId int , projectId int, taskId int,
process1Spent int, process1Lag int, process1AlarmRate varchar2(1) null,
process2Spent int, process2Lag int, process2AlarmRate varchar2(1) null,
process3Spent int, process3Lag int, process3AlarmRate varchar2(1) null
)
ओरेकल क्वेरी:
यह परिणाम) तालिका की तुलना करने के लिए आसान है
SELECT clientId, businessAreaId, projectId,
sum(process1Spent),
sum(process2Spent),
sum(process3Spent),
MIN(process1AlarmRate) KEEP (DENSE_RANK FIRST ORDER BY process1Lag DESC),
MIN(process2AlarmRate) KEEP (DENSE_RANK FIRST ORDER BY process2Lag DESC),
MIN(process3AlarmRate) KEEP (DENSE_RANK FIRST ORDER BY process3Lag DESC)
FROM AlarmReports
GROUP BY GROUPING SETS ((),(clientId),(clientId, projectId),(businessAreaId),(clientId,businessAreaId))
SQL क्वेरी:
(to be continued)
वास्तव में वहाँ
मैं अपने कस्टम सी # साथ wroted कुल डाल करने के लिए योजना बनाई है। अगर कोई दिलचस्पी लेता है, तो कृपया मुझसे संपर्क करें ... कस्टम समेकित ऐसी समस्याओं का सबसे अच्छा समाधान है लेकिन यह वर्चर्स लम्बाई के मामले में अवांछित नहीं है। प्रत्येक वर्कर लंबाई के लिए आपको "विशेष" aggreate फ़ंक्शन
मैं बिना यह एक इसे प्राप्त न करें .. इसे 'आईडीआईडी द्वारा समूह' के बिना कैसे काम करना चाहिए? मेरी क्वेरी हमेशा मुझे 3 प्रविष्टियां लौटाएगी क्योंकि मेरे पास तालिका में 3 अलग-अलग हैं। आपकी क्वेरी परिणाम लौटाएगी जो अलग-अलग आईडीएस की मात्रा पर निर्भर नहीं है, इसलिए यह गलत होना चाहिए? – javagirl
@javagirl - क्या आपने पहले इसे आजमाया था ?, यह काम करेगा। यह कैसे काम करता है, विश्लेषणात्मक कार्यों ('ओवर() ...') में 'भाग' हो सकता है और पूरे स्तर पर समूह करने की आवश्यकता नहीं है। यह तालिका पर मौजूद प्रत्येक पंक्ति के लिए एक मूल्य देता है। – Lamak
मैंने मूल डेटा को गलत तरीके से पढ़ा। समस्या आईडी के बजाए विभाजन में कुछ डालकर तय की जाती है। –