一键选择的UNION列

时间:2019-02-03 21:54:55

标签: sql sql-server

让我们说:

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

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

还有另一个包含有关可用性信息的餐桌优惠:

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,但在三个不同的列中,我试图找到一种将其放入一个ID的方法,而无需重复连接并在3个不同的SELECTS中登录。

我正在使用MSSQL。

3 个答案:

答案 0 :(得分:3)

尝试一下:

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

答案 1 :(得分:2)

如果您的孩子和父母在同一个表格中(项目)

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)

答案 2 :(得分:0)

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可能会返回多次。