简体   繁体   中英

SQL union query to group by a field and project into flattened result set

I am attempting to write a query which will retrieve records from the same table with different conditions and present the results in a flattened format as below:

Desired Result

ID, Word, Translation_From_Region_1007, Translation_From_Region_1006

1, Word1, Test 1, Test 2

2, Word2, Test 3, Test 4

The psuedo-code for my query is below, however I'm not entirely sure how to flatten out the results to display my desired result:

SELECT     Words.ID, Words.Word, Translation
FROM         Words  WHERE RegionId=1007
UNION 
SELECT     Words.ID, Words.Word, Translation
FROM         Words WHERE RegionId=1006

Group by Word (as I only want one instance of the word itself with its respective translations flattened.

If anybody can give me any advice or suggest a better way to do this, I'd be very grateful.

How about this?

select word, max(Translation1006), max(Translation1007)
from
   (SELECT     
       words.word,
       Translation1006 = 
       CASE region
        when 1006 THEN trans
        else NULL
    END,  
    Translation1007 =
    CASE region
        when 1007 THEN trans
        else NULL
    END
    FROM
       words) as detail
group by word

How about something like this?

select A.ID, A.Word, Trans1007 = A.Translation, Trans1006 = B.Translation
    from WORDS A
    left outer join WORDS B on A.ID = B.ID and B.RegionId = 1006
    where A.RegionId = 1007
union
select B.ID, B.Word, Trans1007 = A.Translation, Trans1006 = B.Translation
    from WORDS B
    left outer join WORDS A on B.ID = A.ID and A.RegionId = 1007
    where B.RegionId = 1006

or you can pivot similar to this (which will be better if you have more than just two regions you would like to query on)...

select ID, Word, [1006] as T_1006, [1007] as T_1007
    from (select Id, Word, RegionId, Translation from WORD where RegionId in (1006, 1007)) w
    pivot (
        max(Translation)
        for RegionId in([1006], [1007])
        ) as pvt

If you are using SQL Server, you could in effect flatten the translation putting a comma between each translation entry like so.

SELECT Main.ID, Main.Word, Main.Translations 
FROM(SELECT distinct Words2.ID, Words2.Word,
       (SELECT Words1.Translation + ',' AS [text()]
        FROM WORDS Words1
        WHERE Words1.ID = Words2.ID
        AND Words1.RegionId in (1007, 1006)
        ORDER BY Words1.ID
        For XML PATH ('')) [Translations]
FROM WORDS Words2) [Main]

Another simple example of this can be found via this stack overflow question:

Concatenate many rows into a single text string?

Alternatively, you can find numerous examples of doing this in Oracle here:

http://www.dba-oracle.com/t_display_multiple_column_values_same_rows.htm

    SELECT distinct Words.ID, Words.Word, Translation
    FROM Words  
    WHERE RegionId=1007 or RegionId=1006

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM