简体   繁体   English

UNION 列合二为一 SELECT

[英]UNION columns in one SELECT

Let's say:比方说:

SELECT Item.Id, Item.ParentId FROM Item ..." 

Returns me this data:返回我这个数据:

Id |  ParentId
----------------
1  | NULL
2  | 17
3  | 13

Is there is a way to get this data as one column by using some kind of UNION but on columns from only one SELECT ?有没有一种方法可以通过使用某种UNION但仅来自一个SELECT的列来将此数据作为一列获取? Something like:就像是:

SELECT (Item.Id UNION Item.ParentId) AS Id FROM Item...

Result:结果:

Id |
----
1  | 
2  |
3  |
NULL
17 |
13 |

EDIT EXAMPLE:编辑示例:

I have Media Table:我有媒体表:

Id |  ParentId
----------------
1  | NULL
2  | 1
3  | 2

It have relations with itself, this is some kind of 3 level tree structure (Series -> Seasons -> Episodes)它与自身有关系,这是某种 3 级树结构(系列 -> 季节 -> 剧集)

There is another Table Offer which contain information about availability:还有另一个 Table Offer,其中包含有关可用性的信息:

Id |  MediaId  | Availability
------------------------------
1  | 3         | true

I need to get id's of all media that are available, but also all parent's id, of all levels.我需要获取所有可用媒体的 ID,以及所有级别的所有父级 ID。

I was thinking about:我在想:

SELECT Media.Id, MediaSeason.Id, MediaSeries.Id  FROM Media
LEFT JOIN Media AS MediaSeason ON MediaSeason.Id = Media.ParentId
LEFT JOIN Media AS MediaSeries ON MediaSeries.Id = MediaSeason.ParentId 
LEFT JOIN Offer ON Offer.MediaId = Media.Id
WHERE Offer.Availability = true

This gives me all id's i need but in three different columns and I'm trying to find a way to put it into one, without repeating join and where login in 3 different SELECTS.这给了我所有我需要的 id,但在三个不同的列中,我试图找到一种方法将它放入一个,而无需重复 join 和 login 在 3 个不同的 SELECTS 中。

I'm using MSSQL.我正在使用 MSSQL。

Try this: 尝试这个:

 SELECT * FROM (SELECT Item.Id FROM Item ...
    UNION ALL
    SELECT Item.ParentId FROM Item ...)

If your children and parents are in the same table (Item) 如果您的孩子和父母在同一张桌子中(项目)

SELECT Id FROM Item

Will retrieve all Items, including Parents because parents are also Items. 将检索所有项目,包括父项,因为父级也是项。

But if what you want is to not repeat the where clause and have Ids of any matched Media and its associated parents (even if the parent media does not match the where clause) you can try this: 但是,如果您想要的是不重复where子句,并让任何匹配的Media及其关联的父对象具有ID(即使父媒体与where子句不匹配),也可以尝试以下操作:

SELECT 
    m.Id
FROM
    Media m INNER JOIN (
        SELECT 
            m2.Id, m2.ParentId
        FROM 
            Media m2
            LEFT JOIN Offer ON Offer.MediaId = m2.Id
        WHERE 
            Offer.Availability = true
    ) tmp ON (tmp.Id = m.Id OR tmp.ParentId = m.Id)

Finally, for three levels: 最后,针对三个级别:

SELECT 
    m.Id
FROM
    Media m INNER JOIN (
        SELECT 
            m2.Id, m2.ParentId, m3.ParentId AS GrandParentId
        FROM 
            Media m2
            LEFT JOIN Media m3 ON m2.ParentId = m3.Id
            LEFT JOIN Offer ON Offer.MediaId = m2.Id
        WHERE 
            Offer.Availability = true
    ) tmp ON (tmp.Id = m.Id OR tmp.ParentId = m.Id OR tmp.GrandParentId = m.Id)
SELECT DISTINCT
    pivot_hierarchy.media_id
FROM
    offers  o
LEFT JOIN
    media   m1
        ON m1.id = o.media_id
LEFT JOIN
    media   m2
        ON m2.id = m1.parent_id
OUTER APPLY
(
    SELECT o.media_id
    UNION ALL
    SELECT m1.parent_id WHERE m1.parent_id IS NOT NULL
    UNION ALL
    SELECT m2.parent_id WHERE m2.parent_id IS NOT NULL
)
    AS pivot_hierarchy
WHERE
    o.availability = 'true'

Everything up to the APPLY should be self explanatory. 直到APPLY为止的所有内容都是自我解释。 Get the offers, get the parent of that media if it has one, and the parent of that media if it has one. 获取报价,如果该媒体具有父项,则获取该媒体的父项;如果该媒体具有父项,则获取该媒体的父项。

The APPLY then joins each row on to a function that can return more than one row each. 然后,APPLY将每一行连接到一个函数,该函数可以返回多于一行。 In this case the function returns 1, 2 or 3 rows. 在这种情况下,该函数返回1、2或3行。 Those being the media id, it parent if it has one, and its grand-parent if it has one. 这些是媒体ID,如果有,则为父,如果有,则为祖父母。 To do that, the function unions the three input columns, provided that they're not null. 为此,该函数会合并三个输入列,前提是它们不为空。

This avoids having to join back on to the media table again. 这样避免了必须再次加入媒体表。

Also, you need a distinct in the select. 此外,您还需要一个不同的选择。 Otherwise the same series or season id could return multiple times. 否则,相同的系列或季节ID可能会返回多次。

Nested selects can be avoided in UNION在 UNION 中可以避免嵌套选择

create table tab (
  Id int,
  ParentId int
);

insert into tab 
values
(1, NULL),
(2, 17),
(3, 13);

then do然后做

select ID as ID
from tab
union all
select ParentId as ID
from tab

NOTE: DB queries can be conveniently tested live, eg http://sqlfiddle.com/#!17/7a3a8/2注意:数据库查询可以方便地实时测试,例如http://sqlfiddle.com/#!17/7a3a8/2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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