繁体   English   中英

UNION 列合二为一 SELECT

[英]UNION columns in one SELECT

比方说:

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

返回我这个数据:

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

有没有一种方法可以通过使用某种UNION但仅来自一个SELECT的列来将此数据作为一列获取? 就像是:

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

结果:

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

编辑示例:

我有媒体表:

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

它与自身有关系,这是某种 3 级树结构(系列 -> 季节 -> 剧集)

还有另一个 Table Offer,其中包含有关可用性的信息:

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

我需要获取所有可用媒体的 ID,以及所有级别的所有父级 ID。

我在想:

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

这给了我所有我需要的 id,但在三个不同的列中,我试图找到一种方法将它放入一个,而无需重复 join 和 login 在 3 个不同的 SELECTS 中。

我正在使用 MSSQL。

尝试这个:

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

如果您的孩子和父母在同一张桌子中(项目)

SELECT Id FROM Item

将检索所有项目,包括父项,因为父级也是项。

但是,如果您想要的是不重复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)

最后,针对三个级别:

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'

直到APPLY为止的所有内容都是自我解释。 获取报价,如果该媒体具有父项,则获取该媒体的父项;如果该媒体具有父项,则获取该媒体的父项。

然后,APPLY将每一行连接到一个函数,该函数可以返回多于一行。 在这种情况下,该函数返回1、2或3行。 这些是媒体ID,如果有,则为父,如果有,则为祖父母。 为此,该函数会合并三个输入列,前提是它们不为空。

这样避免了必须再次加入媒体表。

此外,您还需要一个不同的选择。 否则,相同的系列或季节ID可能会返回多次。

在 UNION 中可以避免嵌套选择

create table tab (
  Id int,
  ParentId int
);

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

然后做

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

注意:数据库查询可以方便地实时测试,例如http://sqlfiddle.com/#!17/7a3a8/2

暂无
暂无

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

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