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

फैले हुए जंगल ढूँढना (रिकर्सिव के साथ, PostgreSQL 9.5)

मैंने कुछ समय पहले इसी तरह के एक प्रश्न का उत्तर लिखा था:/ए> . उस प्रश्न में मैंने SQL सर्वर का उपयोग किया था। इंटरमीडिएट सीटीई के विस्तृत विवरण के लिए वह उत्तर देखें। मैंने उस क्वेरी को पोस्टग्रेज़ के लिए अनुकूलित किया।

पथ को text में संयोजित करने के बजाय इसे Postgres सरणी सुविधा का उपयोग करके अधिक कुशलता से लिखा जा सकता है कॉलम।

WITH RECURSIVE
CTE_Idents
AS
(
    SELECT old AS Ident
    FROM identities

    UNION

    SELECT new AS Ident
    FROM identities
)
,CTE_Pairs
AS
(
    SELECT old AS Ident1, new AS Ident2
    FROM identities
    WHERE old <> new

    UNION

    SELECT new AS Ident1, old AS Ident2
    FROM identities
    WHERE old <> new
)
,CTE_Recursive
AS
(
    SELECT
        CTE_Idents.Ident AS AnchorIdent 
        , Ident1
        , Ident2
        , ',' || Ident1 || ',' || Ident2 || ',' AS IdentPath
        , 1 AS Lvl
    FROM 
        CTE_Pairs
        INNER JOIN CTE_Idents ON CTE_Idents.Ident = CTE_Pairs.Ident1

    UNION ALL

    SELECT 
        CTE_Recursive.AnchorIdent 
        , CTE_Pairs.Ident1
        , CTE_Pairs.Ident2
        , CTE_Recursive.IdentPath || CTE_Pairs.Ident2 || ',' AS IdentPath
        , CTE_Recursive.Lvl + 1 AS Lvl
    FROM
        CTE_Pairs
        INNER JOIN CTE_Recursive ON CTE_Recursive.Ident2 = CTE_Pairs.Ident1
    WHERE
        CTE_Recursive.IdentPath NOT LIKE ('%,' || CTE_Pairs.Ident2 || ',%')
)
,CTE_RecursionResult
AS
(
    SELECT AnchorIdent, Ident1, Ident2
    FROM CTE_Recursive
)
,CTE_CleanResult
AS
(
    SELECT AnchorIdent, Ident1 AS Ident
    FROM CTE_RecursionResult

    UNION

    SELECT AnchorIdent, Ident2 AS Ident
    FROM CTE_RecursionResult
)
,CTE_Groups
AS
(
  SELECT
    CTE_Idents.Ident
    ,array_agg(COALESCE(CTE_CleanResult.Ident, CTE_Idents.Ident) 
        ORDER BY COALESCE(CTE_CleanResult.Ident, CTE_Idents.Ident)) AS AllIdents
  FROM
    CTE_Idents
    LEFT JOIN CTE_CleanResult ON CTE_CleanResult.AnchorIdent = CTE_Idents.Ident
  GROUP BY CTE_Idents.Ident
)
SELECT AllIdents
FROM CTE_Groups
GROUP BY AllIdents
;

मैंने एक पंक्ति जोड़ी (7,X,Y) आपके नमूना डेटा के लिए।

SQL Fiddle

परिणाम

|          allidents |
|--------------------|
|   Lydia,Mary,Nancy |
| Albert,Bob,Charles |
|                X,Y |
|                Zoe |



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. रेल कार्यात्मक अनुक्रमणिका पोस्टग्रेज करता है

  2. ऑर्डर_बी के साथ Django क्वेरी, Postgresql पर विशिष्ट और सीमा

  3. PostgreSQL तालिका में प्राथमिक कुंजी बदलें

  4. यादृच्छिक पंक्तियों का चयन करने का सबसे अच्छा तरीका PostgreSQL

  5. PostgreSQL में अल्पविराम के साथ प्रारूप संख्या