2009-12-16 18 views
7

मैंने पिछले कुछ दिनों में इस पर काम किया है और सर्कल में घूम रहा हूं। stackoverflow questionएसक्यूएल सिंटेक्स एकाधिक टेबलों को पिवोट

अब मैं अपने डेटा किसी एकल 400 स्तंभ तालिका से एक और अधिक प्रबंधनीय डेटाबेस संरचना करने के लिए दामिर Sudarevic के लिए कई धन्यवाद के साथ चले गए हैं:

मेरे सवाल का जवाब मैं इस पोस्ट में स्वीकार किए जाते हैं आसपास आधारित है।

मेरे डेटाबेस इस तरह दिखता है:

alt text

CREATE TABLE JobFiles (
    JobID UNIQUEIDENTIFIER PRIMARY KEY, 
    MachineID UNIQUEIDENTIFIER REFERENCES Machines(MachineID), 
    [Desc] NVARCHAR(MAX), 
    Name NVARCHAR(255), 
    JobOpen BIT, 
    [CreateDate] DATETIME NOT NULL DEFAULT GETDATE(), 
    [ModifyDate] DATETIME NOT NULL DEFAULT GETDATE(), 
    [CreatedByUser] NVARCHAR(64) DEFAULT '', 
    [ModifiedByUser] NVARCHAR(64) DEFAULT '') 
GO 

CREATE TABLE JobParamType (
    ParamTypeID UNIQUEIDENTIFIER PRIMARY KEY, 
    Name NVARCHAR(255), 
    [Desc] NVARCHAR(MAX), 
    IsTrait NVARCHAR) 

GO 
CREATE TABLE JobParamGroup (
    ParamGroupID UNIQUEIDENTIFIER PRIMARY KEY, 
    Name NVARCHAR(255), 
    [Desc] NVARCHAR(MAX)) 

GO 


CREATE TABLE JobParams (
    ParamID UNIQUEIDENTIFIER PRIMARY KEY, 
    ParamTypeID UNIQUEIDENTIFIER REFERENCES JobParamType(ParamTypeID), 
    ParamGroupID UNIQUEIDENTIFIER REFERENCES JobParamGroup(ParamGroupID), 
    JobFileID UNIQUEIDENTIFIER REFERENCES JobFiles(JobID), 
    IsEnabled BIT) 

GO 

-- Text based property 
CREATE TABLE JobTrait (
    ParamID UNIQUEIDENTIFIER PRIMARY KEY REFERENCES JobParams(ParamID), 
    Value NVARCHAR(MAX)) 
GO 

-- Numeric based property 
CREATE TABLE JobMeasurement (
    ParamID UNIQUEIDENTIFIER PRIMARY KEY REFERENCES JobParams(ParamID), 
    Value FLOAT, 
    Format NVARCHAR(20), 
    Unit NVARCHAR(MAX)) 
GO 

हालांकि, अपने आवेदन के एक विशेष समारोह के लिए मैं एक JobMeasurement.Value या JobTrait वाले कॉलम के रूप में हर JobParamType.Name पंक्ति सूची की जरूरत है। प्रत्येक JobFiles.Name के लिए इसके डेटा के रूप में मूल्य।

जॉबप्रैम टाइप। आईएसट्रेट का उपयोग यह निर्धारित करने के लिए किया जाता है कि कोई मान मापन या विशेषता है या नहीं।

यानी

JobName | ParamName1  | ParamName2  | ParamName3  ... | ParamName400 
"MyJob"  MesurementValue TraitValue   MesurementValue ... TraitValue 
"TestJob" MesurementValue TraitValue   MesurementValue ... TraitValue 
"Job2"  MesurementValue TraitValue   MesurementValue ... TraitValue 

etc 

मैं पिवट तालिकाओं के साथ खेल रहे हैं और उदाहरण देख रही है और उन्हें का पालन करके JobParamType तालिका में कॉलम पाने में कामयाब रहे है लेकिन अब यह काफी जटिल हो रही है क्योंकि मेरे डेटा के बीच विभाजित है कई टेबल और यह मेरे सिर को चोट लगाना शुरू कर रहा है !!!

DECLARE @cols NVARCHAR(MAX) 
SELECT @cols = STUFF((SELECT DISTINCT TOP 10 PERCENT 
           '],[' + tParams.Name 
         FROM dbo.JobParamType AS tParams 
         ORDER BY '],[' + tParams.Name 
         FOR XML PATH('') 
        ), 1, 2, '') + ']' 
print @cols 

मुझे उम्मीद है कि कोई मुझे पिवोटिंग और डेटा को एकाधिक तालिकाओं से प्राप्त करने में मदद कर सकता है।

मुझे उम्मीद है कि यह समझ में आता है और मैं आपकी मदद और चर्चाओं की प्रतीक्षा करता हूं।

उन्नत में धन्यवाद।

उत्तर

8

मैं this model से कुछ उदाहरण पोस्ट करूंगा - क्योंकि मेरे पास पहले से ही है। दोनों मॉडल बहुत समान हैं, इसलिए आपको इस तकनीक को अपनाने में बहुत अधिक परेशानी नहीं होनी चाहिए।

जब सिरदर्द की बात आती है, तो मुझे लगता है कि सबसे आसान तरीका चरण-दर-चरण जाना है, और बाद में अनुकूलित करना है।

चरण 1
मॉडल को फ़्लैट करने के लिए एक दृश्य बनाएं; (see the model)

CREATE VIEW dbo.vProperties AS 
SELECT m.MachineID AS [Machine ID] 
,s.SetupID AS [Setup ID] 
,p.PropertyID AS [Property ID] 
,t.PropertyTypeID AS [Property Type ID] 
,m.Name AS [Machine Name] 
,s.Name AS [Setup Name] 
,t.Name AS [Property Type Name] 
,t.IsTrait AS [Is Trait] 
,x.Value AS [Measurement Value] 
,x.Unit AS [Unit] 
,y.Value AS [Trait] 
FROM dbo.Machine AS m 
JOIN dbo.Setup AS s ON s.MachineID = m.MachineID 
JOIN dbo.Property AS p ON p.SetupID = s.SetupID 
JOIN dbo.PropertyType AS t ON t.PropertyTypeID = p.PropertyTypeID 
LEFT JOIN dbo.Measurement AS x ON x.PropertyID = p.PropertyID 
LEFT JOIN dbo.Trait AS y ON y.PropertyID = p.PropertyID 

चरण 2

केवल [Setup Name], [Property Type Name], [Value] उत्पन्न करने के लिए एक दृश्य बनाएं; ध्यान दें कि इस में माप मूल्य और विशेषता उसी कॉलम में समाप्त होती है। आप शायद JobName, ParameterTypeName, Value

CREATE VIEW dbo.vSetupValues AS 
SELECT [Setup Name] 
     ,[Property Type Name] 
     ,COALESCE(cast([Measurement Value] AS varchar(50)), [Trait]) AS [Val] 
FROM dbo.vProperties 

चरण 3 का प्रयोग करेंगे।

द्वारा

DECLARE @Props TABLE (
id int IDENTITY (1,1) 
,PropName varchar(50) 
); 

INSERT INTO @Props (PropName) 
SELECT DISTINCT [Name] 
FROM dbo.PropertyType 

चरण 4 ऑर्डर करने के लिए एक स्तंभ के साथ गुण (पैरामीटर) की सूची बनाएं।

अब मैं गतिशील क्वेरी पाठ

DECLARE @qw TABLE(
id int IDENTITY (1,1) 
, txt nchar(500) 
) 

INSERT INTO @qw (txt) 
    SELECT 'SELECT' UNION 
    SELECT '[Setup Name]' ; 

INSERT INTO @qw (txt) 
    SELECT ',MAX(CASE [Property Type Name] WHEN ''' + PropName 
    + ''' THEN Val ELSE NULL END) AS [' + PropName + ']' 
    FROM @Props 
    ORDER BY id; 

INSERT INTO @qw (txt) 
SELECT 'FROM dbo.vSetupValues' UNION 
SELECT 'GROUP BY [Setup Name]' UNION 
SELECT 'ORDER BY [Setup Name]'; 

चरण 5 पैदा करेगा।

और यहाँ, क्वेरी का पाठ है इस बिंदु मैं एक संग्रहीत प्रक्रिया है, एक और दृश्य में इस पैकेज कर सकते हैं के रूप में, या एक चर के रूप में गतिशील एसक्यूएल का उपयोग करने में।
alt text http://www.damirsystems.com/dp_images/machinesetup_results.png


अद्यतन:

SELECT txt FROM @qw 

रिटर्न

SELECT                                                                                                                            
[Setup Name]                                                                                                                           
,MAX(CASE [Property Type Name] WHEN 'Diameter LSL' THEN [Val] ELSE NULL END) AS [Diameter LSL]                                                                                                      
,MAX(CASE [Property Type Name] WHEN 'Diameter USL' THEN [Val] ELSE NULL END) AS [Diameter USL]                                                                                                      
,MAX(CASE [Property Type Name] WHEN 'Force LSL' THEN [Val] ELSE NULL END) AS [Force LSL]                                                                                                        
,MAX(CASE [Property Type Name] WHEN 'Force USL' THEN [Val] ELSE NULL END) AS [Force USL]                                                                                                        
,MAX(CASE [Property Type Name] WHEN 'Leak LSL' THEN [Val] ELSE NULL END) AS [Leak LSL]                                                                                                        
,MAX(CASE [Property Type Name] WHEN 'Leak USL' THEN [Val] ELSE NULL END) AS [Leak USL]                                                                                                        
,MAX(CASE [Property Type Name] WHEN 'Press Travel LSL' THEN [Val] ELSE NULL END) AS [Press Travel LSL]                                                                                                    
,MAX(CASE [Property Type Name] WHEN 'Press Travel USL' THEN [Val] ELSE NULL END) AS [Press Travel USL]                                                                                                    
,MAX(CASE [Property Type Name] WHEN 'Seal Height LSL' THEN [Val] ELSE NULL END) AS [Seal Height LSL]                                                                                                     
,MAX(CASE [Property Type Name] WHEN 'Seal Height USL' THEN [Val] ELSE NULL END) AS [Seal Height USL]                                                                                                     
FROM dbo.vSetupValues                                                                                                                        
GROUP BY [Setup Name]                                                                                                                        
ORDER BY [Setup Name]          

और अगर मैं इस चलाने के चरण 4 में निश्चित बग, था अधिकतम लापता() और परिणाम उदाहरण गयी।

+0

धन्यवाद ... अपना समय और प्रयासों की बहुत सराहना कर रहे हैं। पहले से कहीं अधिक जटिल बिट करें हालांकि यह कार्य आज आपके उदाहरण के माध्यम से निकल जाएगा और इसे चरणों में तोड़ देगा। – Belliez

+0

दमीर, आपका प्रतिभा, धन्यवाद। यह पूरी तरह से काम करता है। बस एक आखिरी सवाल। मैं इस आदेश को आपके ऊपर कैसे चलाऊंगा। चरण 5 किसी तालिका में आदेश (एसक्यूएल प्रबंधन स्टूडियो के माध्यम से) प्रदर्शित "@qw से TXT का चयन करें" और मैं कॉपी करें और एक नई क्वेरी में पेस्ट करने के लिए है। फिर, धन्यवाद – Belliez

+0

विचार करने के लिए "पैकेज" एक दृश्य, एक प्रक्रिया या एक चर में अंतिम क्वेरी है - कितनी बार मानकों की अपनी सूची को बदल सकता है पर निर्भर करता है। यदि उन 400 पैरामीटर साल में कुछ बार बदलते हैं, तो दृश्य का उपयोग करें और मैन्युअल रूप से परिवर्तन बनाएं। यदि वे प्रतिदिन बदलते हैं, तो इसे एक चर में रखें और गतिशील एसक्यूएल के रूप में निष्पादित करें - चरण 3 और 4 स्वचालित करें। –

संबंधित मुद्दे