मैं एक परिसंपत्ति डेटाबेस एक पदानुक्रम है पर काम कर रहा हूँ की क्वेरी। इसके अलावा, एक "संदर्भ एसेट" तालिका है, जो प्रभावी रूप से किसी संपत्ति को इंगित करती है। संदर्भ संपत्ति मूल रूप से ओवरराइड के रूप में कार्य करती है, लेकिन यह चुना जाता है जैसे कि यह एक अद्वितीय, नई संपत्ति थी। सेट होने वाले ओवरराइड में से एक है, parent_id है।एसक्यूएल सर्वर: श्रेणीबद्ध और संदर्भित डाटा
कॉलम कि पदानुक्रम का चयन के लिए प्रासंगिक हैं:
एसेट: आईडी (प्राथमिक), PARENT_ID
एसेट संदर्भ: आईडी (प्राथमिक), ASSET_ID (foreignkey-> एसेट), PARENT_ID (हमेशा एक परिसंपत्ति)
- --EDITED 5/27 ----
नमूना प्रासंगिक तालिका डेटा (के बाद मिलती है):
id | asset_id | name | parent_id | milestone | type 3 3 suit null march shape 4 4 suit_banker 3 april texture 5 5 tie null march shape 6 6 tie_red 5 march texture 7 7 tie_diamond 5 june texture -5 6 tie_red 4 march texture
आईडी < 0 (अंतिम पंक्ति की तरह) संदर्भित संपत्तियों को इंगित करें। संदर्भित संपत्तियों में कुछ कॉलम हैं जिन्हें ओवरराइड किया गया है (इस मामले में, केवल parent_id महत्वपूर्ण है)।
उम्मीद है कि अगर मैं अप्रैल से सभी परिसंपत्तियों का चयन करें, मैं मिलते जुलते क्वैरी के पूरे पेड़ की शाखाओं को पाने के लिए एक उच्च माध्यमिक का चयन करना चाहिए है: तो शुरू में क्वेरी मिलान परिणाम होगा
में:
4 4 suit_banker 3 april texture
फिर CTE के बाद, हम पूरा पदानुक्रम हो और हमारे परिणाम यह (अब तक इस काम कर रहा है)
0 होना चाहिए3 3 suit null march shape 4 4 suit_banker 3 april texture -5 6 tie_red 4 march texture
और आप देखते हैं, आईडी की मूल: -5 वहाँ है, लेकिन क्या याद आ रही है, कि जरूरत है, संदर्भित संपत्ति है, और संदर्भित संपत्ति की मूल:
5 5 tie null march shape 6 6 tie_red 5 march texture
वर्तमान में मेरे समाधान इस के लिए काम करता है, लेकिन यह केवल संदर्भ की एक भी गहराई तक ही सीमित है (और मुझे लगता है कि कार्यान्वयन काफी बदसूरत है)।
--- संपादित ---- यहाँ मेरी प्राथमिक चुनाव समारोह है। यह बेहतर प्रदर्शन करना चाहिए कि वास्तविक जटिलता कहां है: संपत्ति संदर्भ।
Select A.id as id, A.id as asset_id, A.name,A.parent_id as parent_id, A.subPath, T.name as typeName, A2.name as parent_name, B.name as batchName,
L.name as locationName,AO.owner_name as ownerName, T.id as typeID,
M.name as milestoneName, A.deleted as bDeleted, 0 as reference, W.phase_name, W.status_name
FROM Asset as A Inner Join Type as T on A.type_id = T.id
Inner Join Batch as B on A.batch_id = B.id
Left Join Location L on A.location_id = L.id
Left Join Asset A2 on A.parent_id = A2.id
Left Join AssetOwner AO on A.owner_id = AO.owner_id
Left Join Milestone M on A.milestone_id = M.milestone_id
Left Join Workflow as W on W.asset_id = A.id
where A.deleted <= @showDeleted
UNION
Select -1*AR.id as id, AR.asset_id as asset_id, A.name, AR.parent_id as parent_id, A.subPath, T.name as typeName, A2.name as parent_name, B.name as batchName,
L.name as locationName,AO.owner_name as ownerName, T.id as typeID,
M.name as milestoneName, A.deleted as bDeleted, 1 as reference, NULL as phase_name, NULL as status_name
FROM Asset as A Inner Join Type as T on A.type_id = T.id
Inner Join Batch as B on A.batch_id = B.id
Left Join Location L on A.location_id = L.id
Left Join Asset A2 on AR.parent_id = A2.id
Left Join AssetOwner AO on A.owner_id = AO.owner_id
Left Join Milestone M on A.milestone_id = M.milestone_id
Inner Join AssetReference AR on AR.asset_id = A.id
where A.deleted <= @showDeleted
मेरे पास एक संग्रहीत प्रक्रिया है जो एक temp तालिका (#temp) लेती है और पदानुक्रम के सभी तत्व पाती है।रणनीति मैं कार्यरत था इस:
- # से
- क्वेरी से मेल खाता संपत्ति के पूरे पदानुक्रम जाओ एक अस्थायी तालिका में पूरे सिस्टम पदानुक्रम (#treeIDs) प्रत्येक पूरे पेड़ की टहनी की अल्पविराम द्वारा अलग सूची के प्रतिनिधित्व का चयन करें (अस्थायी)
- जाओ सभी संदर्भ संपत्ति पदानुक्रम
- से आस्तियों द्वारा की ओर इशारा किया सभी संदर्भ संपत्ति
यह अब के लिए काम करता है के पदानुक्रम पार्स संदर्भ संपत्ति हमेशा से रहे हैं क्योंकि ला एक शाखा पर सेंट आइटम, लेकिन अगर वे नहीं थे, तो मुझे लगता है कि मैं परेशानी में होगा। मुझे लगता है कि मुझे रिकर्सन के कुछ बेहतर रूप की आवश्यकता है।
यहाँ मेरे वर्तमान कोड है, जो काम कर रहा है, लेकिन मैं इसे पर गर्व नहीं कर रहा हूँ, और मुझे पता है कि यह मजबूत नहीं है (क्योंकि यह तभी काम करता है के संदर्भ तल पर हैं):
चरण 1। संपूर्ण पदानुक्रम
;WITH Recursive_CTE AS (
SELECT Cast(id as varchar(100)) as Hierarchy, parent_id, id
FROM #assetIDs
Where parent_id is Null
UNION ALL
SELECT
CAST(parent.Hierarchy + ',' + CAST(t.id as varchar(100)) as varchar(100)) as Hierarchy, t.parent_id, t.id
FROM Recursive_CTE parent
INNER JOIN #assetIDs t ON t.parent_id = parent.id
)
Select Distinct h.id, Hierarchy as idList into #treeIDs
FROM (Select Hierarchy, id FROM Recursive_CTE) parent
CROSS APPLY dbo.SplitIDs(Hierarchy) as h
चरण 2. निर्माण सभी परिसंपत्तियों क्वेरी से मेल खाने
Select DISTINCT L.id into #RelativeIDs FROM #treeIDs
CROSS APPLY dbo.SplitIDs(idList) as L
WHERE #treeIDs.id in (Select id FROM #temp)
चरण 3. की शाखाओं का चयन करें जाओ सभी संदर्भ आस्तियों शाखाओंमें 63,210 (संदर्भ संपत्ति, नकारात्मक आईडी मान हैं इसलिए आईडी < 0 हिस्सा)
Select asset_id INTO #REFLinks FROM #AllAssets WHERE id in
(Select #AllAssets.asset_id FROM #AllAssets Inner Join #RelativeIDs
on #AllAssets.id = #RelativeIDs.id Where #RelativeIDs.id < 0)
चरण 4. कुछ भी की शाखाओं हो जाओ कदम 3
Select DISTINCT L.id into #extraRelativeIDs FROM #treeIDs
CROSS APPLY dbo.SplitIDs(idList) as L
WHERE
exists (Select #REFLinks.asset_id FROM #REFLinks WHERE #REFLinks.asset_id = #treeIDs.id)
and Not Exists (select id FROM #RelativeIDs Where id = #treeIDs.id)
मैं सिर्फ दिखाने के लिए कोशिश की है में पाया प्रासंगिक कोड मैं किसी भी व्यक्ति के लिए बहुत आभारी हूं जो मुझे बेहतर समाधान खोजने में मदद कर सकता है!
आप किस एसक्यूएल संस्करण का उपयोग कर रहे हैं? http://msdn.microsoft.com/de-de/library/bb677290.aspx – NickD
एसक्यूएल सर्वर 2012, लेकिन हमने अभी इसे स्विच किया है, इसलिए इनमें से अधिकांश 2008 – haggercody