Sql 将多个表中的值作为一个resultset中的字段返回

Sql 将多个表中的值作为一个resultset中的字段返回,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有以下查询,它返回一组结果,其中填充了另一个表中的值: select mjc, name, (SELECT TOP 1 pageID FROM page WHERE mjc = 'ABC' ORDER BY createdOn DESC) AS LastCreatedId, (SELECT TOP 1 pageName FROM page WHERE mjc = 'ABC' ORDER BY createdOn DESC) AS LastCreatedName,

我有以下查询,它返回一组结果,其中填充了另一个表中的值:

select  mjc,
    name,
    (SELECT TOP 1 pageID FROM page WHERE mjc = 'ABC' ORDER BY createdOn DESC) AS LastCreatedId,
    (SELECT TOP 1 pageName FROM page WHERE mjc = 'ABC' ORDER BY createdOn DESC) AS LastCreatedName,
    (SELECT TOP 1 createdOn FROM page WHERE mjc = 'ABC' ORDER BY createdOn DESC) AS LastCreatedDate,
    (SELECT TOP 1 pageID FROM page WHERE mjc = 'ABC' ORDER BY modifiedOn DESC) AS LastEditedId,
    (SELECT TOP 1 pageName FROM page WHERE mjc = 'ABC' ORDER BY modifiedOn DESC) AS LastEditedName,
    (SELECT TOP 1 modifiedOn FROM page WHERE mjc = 'ABC' ORDER BY modifiedOn DESC) AS LastEditedDate,
    (SELECT COUNT(*) FROM page WHERE mjc = 'ABC' AND published = 1) AS PublishedPages,
    (SELECT COUNT(*) FROM page WHERE mjc = 'ABC' AND published = 0) AS UnpublishedPages
from mags
WHERE mjc IN ('ABC')

我只是想知道是否有一种更有效的方法来实现这一点,例如使用连接?

您可以在一定程度上优化子查询。这些预测如下:

(SELECT TOP 1 pageID FROM page WHERE mjc = 'ABC' ORDER BY createdOn DESC),
(SELECT TOP 1 pageName FROM page WHERE mjc = 'ABC' ORDER BY createdOn DESC),
(SELECT TOP 1 createdOn FROM page WHERE mjc = 'ABC' ORDER BY createdOn DESC),
也可以这样重新编写:

SELECT t.pageID AS LastCreatedId, 
       t.pageName AS LastCreatedName, 
       t.createdOn AS LastCreatedDate
FROM (SELECT TOP 1 pageID, pageName, createdOn
      FROM page where mjc = 'ABC' ORDER BY createdOn DESC) t
或者在更大的背景下

SELECT
    mjc,
    name,
    t.pageID AS LastCreatedId, 
    t.pageName AS LastCreatedName, 
    t.createdOn AS LastCreatedDate
FROM mags,
    (SELECT TOP 1 pageID, pageName, createdOn
     FROM page where mjc = 'ABC' ORDER BY createdOn DESC) t
WHERE mjc IN ('ABC')

这样可以避免运行同一子查询3次。同样的优化也可以用于
lastededid,lastedname,lastededidate

我想应该是这样的 但我不确定它会给你同样的结果。 当然,如果我看到结果,我会调整它。但举个例子:



我认为您还可以使用
max()
来获得最后一次
modifiedOn
createdOn
而不是使用两个查询

希望它能帮助您尝试:

select m.mjc,
       m.name,
       s.*
from mags m
join 
(select mjc,
        max(case when cr_rn = 1 then pageID end) LastCreatedId,
        max(case when cr_rn = 1 then pageName end) LastCreatedName,
        max(case when cr_rn = 1 then createdOn end) LastCreatedDate,
        max(case when mo_rn = 1 then pageID end) LastEditedId,
        max(case when mo_rn = 1 then pageName end) LastEditedName,
        max(case when mo_rn = 1 then modifiedOn end) LastEditedDate,
        sum(case published when 1 then 1 else 0 end) PublishedPages,
        sum(case published when 0 then 1 else 0 end) UnpublishedPages
 from (select p.*,
             row_number() over (order by createdOn desc) cr_rn,
             row_number() over (order by modifiedOn desc) mo_rn,
       from page where mjc = 'ABC') pa
 group by mjc) s
on m.mjc=s.mjc
WHERE m.mjc IN ('ABC')

-对于单个页面的访问。如果要选择多个mjc值,请将
partitionbyMJC
添加到行数字段的
over
子句中。

Jeez,这可能是最佳解决方案,但可读性不强:-)太糟糕了,SQL Server不支持
FIRST\u VALUE()
窗口函数。。。
select m.mjc,
       m.name,
       s.*
from mags m
join 
(select mjc,
        max(case when cr_rn = 1 then pageID end) LastCreatedId,
        max(case when cr_rn = 1 then pageName end) LastCreatedName,
        max(case when cr_rn = 1 then createdOn end) LastCreatedDate,
        max(case when mo_rn = 1 then pageID end) LastEditedId,
        max(case when mo_rn = 1 then pageName end) LastEditedName,
        max(case when mo_rn = 1 then modifiedOn end) LastEditedDate,
        sum(case published when 1 then 1 else 0 end) PublishedPages,
        sum(case published when 0 then 1 else 0 end) UnpublishedPages
 from (select p.*,
             row_number() over (order by createdOn desc) cr_rn,
             row_number() over (order by modifiedOn desc) mo_rn,
       from page where mjc = 'ABC') pa
 group by mjc) s
on m.mjc=s.mjc
WHERE m.mjc IN ('ABC')