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

एक ही पंक्ति में सभी बच्चों के साथ एकल माता-पिता प्राप्त करें

आपका उदाहरण पिवट करने के करीब है, लेकिन मुझे नहीं लगता कि इस पर पिवट कार्यक्षमता प्रयोग योग्य है।

मैंने आपके उदाहरण का नाम बदलकर "बच्चे-माता-पिता" के बजाय "विभाग-व्यक्ति" का उपयोग करने के लिए किया है, बस मेरी पवित्रता बनाए रखने के लिए।

तो, पहले टेबल और कुछ डेटा

DECLARE @Department TABLE
  ( 
   DepartmentID int
  ,DepartmentName varchar(50)
  )
DECLARE @Person TABLE
  ( 
   PersonID int
  ,PersonName varchar(50)
  ,DepartmentID int
  )

INSERT  INTO @Department
  ( DepartmentID, DepartmentName )
 SELECT 1, 'Accounting' UNION
 SELECT 2, 'Engineering' UNION
 SELECT 3, 'Sales' UNION
 SELECT 4, 'Marketing' ;

INSERT  INTO @Person
  ( PersonID, PersonName, DepartmentID )
 SELECT 1, 'Lyne', 1 UNION
 SELECT 2, 'Damir', 2 UNION
 SELECT 3, 'Sandy', 2 UNION
 SELECT 4, 'Steve', 3 UNION
 SELECT 5, 'Brian', 3 UNION
 SELECT 6, 'Susan', 3 UNION
 SELECT 7, 'Joe', 4 ;

अब मैं मॉडल को समतल करना चाहता हूं, मैं अस्थायी तालिका का उपयोग करूंगा क्योंकि मेरे पास तालिका चर हैं - लेकिन "वास्तविक तालिकाओं" पर एक दृश्य भी अच्छा होगा।

/*  Create a table with:
    DepartmentID, DepartmentName, PersonID, PersonName, PersonListIndex

 This could be a view instead of temp table. 
*/
IF object_id('tempdb.dbo.#tmpTbl','U') IS NOT NULL
 DROP TABLE #tmpTbl

;
WITH  prs
        AS ( SELECT PersonID
                   ,PersonName
                   ,DepartmentID
                   ,row_number() OVER ( PARTITION BY DepartmentID ORDER BY PersonID ) AS [PersonListIndex]
             FROM   @Person
           ),
      dptprs
        AS ( SELECT d.DepartmentID
                   ,d.DepartmentName
                   ,p.PersonID 
                   ,p.PersonName
                   ,p.PersonListIndex
             FROM   @Department AS d
                    JOIN prs AS p ON p.DepartmentID = d.DepartmentID
           )
SELECT * INTO #tmpTbl FROM dptprs

-- SELECT * FROM #tmpTbl

डायनेमिक कॉलम का अर्थ है डायनेमिक क्वेरी, मैं इसे पंक्ति-दर-पंक्ति एक तालिका में लिखूंगा

/* Table to compose dynamic query */
DECLARE @qw TABLE
  ( 
   id int IDENTITY(1, 1)
  ,txt nvarchar(500)
  )

/* Start composing dynamic query */
INSERT  INTO @qw ( txt ) VALUES  ( 'SELECT' ) 
INSERT  INTO @qw ( txt ) VALUES  ( '[DepartmentID]' )
INSERT  INTO @qw ( txt ) VALUES  ( ',[DepartmentName]' ) ;


/* fetch max number of employees in a department */
DECLARE @i int ,@m int
SET @m = (SELECT max(PersonListIndex) FROM #tmpTbl)

/* Compose dynamic query */
SET @i = 1
WHILE @i <= @m 
  BEGIN  
      INSERT  INTO @qw ( txt )
            SELECT  ',MAX(CASE [PersonListIndex] WHEN '
                    + cast(@i AS varchar(10)) + ' THEN [PersonID] ELSE NULL END) AS [Person_'
                    + cast(@i AS varchar(10)) + '_ID]'

      INSERT  INTO @qw ( txt )
            SELECT  ',MAX(CASE [PersonListIndex] WHEN '
                    + cast(@i AS varchar(10)) + ' THEN [PersonName] ELSE NULL END) AS [Person_'
                    + cast(@i AS varchar(10)) + '_Name]'  

    SET @i = @i + 1
  END

/* Finish the dynamic query */
INSERT  INTO @qw (txt) VALUES ( 'FROM #tmpTbl' )
INSERT  INTO @qw (txt) VALUES ( 'GROUP BY [DepartmentID], [DepartmentName]' )
INSERT  INTO @qw (txt) VALUES ( 'ORDER BY [DepartmentID]' )

-- SELECT * FROM @qw

और अब, सभी क्वेरी पंक्तियों को एक वेरिएबल में संयोजित करें और निष्पादित करें

/* Create a variable with dynamic sql*/
DECLARE @exe nvarchar(4000)
SET @exe=''
SELECT  @exe = @exe + txt + ' ' FROM @qw ORDER BY id

/* execute dynamic sql */
EXEC master..sp_executesql @exe

और यहाँ परिणाम है:



  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, दिनांक/समय के बीच चयन

  2. दो पंक्तियों की तुलना करें और उन स्तंभों की पहचान करें जिनके मान भिन्न हैं

  3. SQL तालिका से डेटा सम्मिलित करना और बदलना

  4. डेटाटाइम के लिए एसएसआईएस स्रोत प्रारूप निहित रूपांतरण

  5. SQL सर्वर में 1 लाख पंक्तियों को हटाना