views:

84

answers:

3

I have this query:

SELECT DISTINCT IM.EDIFICIOS_ID, TI.TITULAR
FROM IMPORTACION IM
INNER JOIN I_EDIFICIO IE ON IM.IMPORTACION_ID=IE.IMPORTACION_ID
INNER JOIN I_EDIFICIO_TITULAR ET ON IM.IMPORTACION_ID=ET.IMPORTACION_ID AND IE.EDIFICIO_ID=ET.EDIFICIO_ID
INNER JOIN I_TITULAR TI ON IM.IMPORTACION_ID=TI.IMPORTACION_ID AND ET.TITULAR_ID=TI.TITULAR_ID
WHERE TI.TITULAR IS NOT NULL AND TI.TITULAR<>''
ORDER BY IM.EDIFICIOS_ID, TI.TITULAR;

that returns this result set:

EDIFICIOS_ID TITULAR
------------ ------------------
1911         Ana María García
1911         Anselmo Piedrahita
1911         Manuel López
2594         Carlos Pérez
2594         Felisa García
6865         Carlos Pérez
6865         Felisa García
8428         Carlos Pérez

I want to concatenate the values from TITULAR for each EDIFICIOS_ID, so I get this:

EDIFICIOS_ID TITULAR
------------ ------------------
1911         Ana María García; Anselmo Piedrahita; Manuel López
2594         Carlos Pérez; Felisa García
6865         Carlos Pérez; Felisa García
8428         Carlos Pérez

I'm trying to use the FOR XML PATH trick. I've used it in the past but, since I can't really understand how it works, I can't figure out how to apply it to this specific case. Can you provide me with some ideas?

A: 

This seems similar to this question on SO - you might find it useful in answering your question. It is specifically about MySQL not sql server, but anyway, check it out.


Edit:

It looks like you may have to simulate group_concat for SQL Server - here's a SO question that discusses that.

Hope that helps some.


Edit 2:

But that does make me wonder why you don't just do this on the client app and not via SQL. It seems it would be straightforward enough to accomplish this with the retrieved table that has duplicated int values. Perhaps that might be an approach to take?

itsmatt
Thank you for the links but SQL Server does not have a builtin function like MySQL. I'm aware of the XML PATH trick to emulate it; my problem is that I only know how to apply it to the examples given, not to my query.
Álvaro G. Vicario
The client module is based in a large query that returns a row per item. Altering any of these (more that one query or more than one row per item) would be a mayor change.
Álvaro G. Vicario
+2  A: 

try something like this:

DECLARE @TableA  table (EDIFICIOS_ID int, TITULAR nvarchar(500))
INSERT INTO @TableA VALUES (1911 ,'Ana María García')
INSERT INTO @TableA VALUES (1911 ,'Anselmo Piedrahita')
INSERT INTO @TableA VALUES (1911 ,'Manuel López')
INSERT INTO @TableA VALUES (2594 ,'Carlos Pérez')
INSERT INTO @TableA VALUES (2594 ,'Felisa García')
INSERT INTO @TableA VALUES (6865 ,'Carlos Pérez')
INSERT INTO @TableA VALUES (6865 ,'Felisa García')
INSERT INTO @TableA VALUES (8428 ,'Carlos Pérez')

;with ResutSet AS
(
    SELECT EDIFICIOS_ID,TITULAR FROM @TableA
    --replace with your query here and don't use @TableA
    --  SELECT DISTINCT IM.EDIFICIOS_ID, TI.TITULAR
    --  FROM IMPORTACION IM
    --  INNER JOIN I_EDIFICIO IE ON IM.IMPORTACION_ID=IE.IMPORTACION_ID
    --  INNER JOIN I_EDIFICIO_TITULAR ET ON IM.IMPORTACION_ID=ET.IMPORTACION_ID AND IE.EDIFICIO_ID=ET.EDIFICIO_ID
    --  INNER JOIN I_TITULAR TI ON IM.IMPORTACION_ID=TI.IMPORTACION_ID AND ET.TITULAR_ID=TI.TITULAR_ID
    --  WHERE TI.TITULAR IS NOT NULL AND TI.TITULAR<>''
    --  ORDER BY IM.EDIFICIOS_ID, TI.TITULAR;
)
SELECT
    c1.EDIFICIOS_ID
        ,STUFF(
                 (SELECT
                      '; ' + TITULAR
                      FROM ResutSet  c2
                      WHERE c2.EDIFICIOS_ID=c1.EDIFICIOS_ID
                      ORDER BY c1.EDIFICIOS_ID, TITULAR
                      FOR XML PATH('') 
                 )
                 ,1,2, ''
              ) AS CombinedValue
    FROM ResutSet c1
    GROUP BY c1.EDIFICIOS_ID
    ORDER BY c1.EDIFICIOS_ID

OUTPUT:

EDIFICIOS_ID CombinedValue
------------ ---------------------------------------------------
1911         Ana María García; Anselmo Piedrahita; Manuel López
2594         Carlos Pérez; Felisa García
6865         Carlos Pérez; Felisa García
8428         Carlos Pérez

(4 row(s) affected)
KM
It seems to work fine. And, although I still cannot say I fully understand the whole FOR XML PATH mechanism, the query format you propose (an aliased result set) makes it cleaner that the examples in the articles I've read so I think I'll eventually get it ;-)
Álvaro G. Vicario
@Álvaro G. Vicario, I hope this helps: Your query is encapsulated within a CTE as "ResultSet", because I needed to use it two times. the "c1" query gets 1 row per EDIFICIOS_ID value. Then for each row returned from "c1", a "STUFF" command is run on the "magic" xml concatenation of the "c2" query.
KM
I've tagged it as accepted answer. I've been using in several places and it's very easy to adapt it to other queries. It goes straight into my bookmarks.
Álvaro G. Vicario
A: 

This is not exactly +who are you looking for, but there are another way on MSSQL to concatenate values.

    SELECT DISTINCT 
    1 AS TAG,
    NULL AS PARENT,
    EDIFICIOS_ID AS [EDIFICIOS!1!EDIFICIOS_ID],
    NULL AS [EDIFICIOS!1!TITULAR!IDREFS]
FROM 
    @TABLEA
UNION ALL
SELECT DISTINCT  
    1 AS TAG,
    NULL AS PARENT,
    EDIFICIOS_ID AS [EDIFICIOS!1!EDIFICIOS_ID],
    TITULAR+';' AS  [EDIFICIOS!1!TITULAR!IDREFS]
FROM 
    @TABLEA
ORDER BY 
    [EDIFICIOS!1!EDIFICIOS_ID]
FOR XML EXPLICIT
guille
Hmmm... I just get a single value with an XML string. Never mind, I'd never be able to understand how it works ;-)
Álvaro G. Vicario