将许多表中的值作为一个结果集中的字段返回

时间:2012-02-12 11:40:07

标签: 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 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')

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

3 个答案:

答案 0 :(得分:4)

您可以在某种程度上优化子查询。这些预测在这里:

(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次。可以对LastEditedId, LastEditedName, LastEditedDate

进行相同的优化

答案 1 :(得分:2)

尝试:

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值,请将partition by mjc添加到row_number字段的over子句中。

答案 2 :(得分:1)

我认为会是这样的 但我不确定它会给你相同的结果。 如果我看到结果,我会调整它。但仅作为一个例子:


select top 1 m.mjc,m.name,
       p.pageID,p.pageName,p.createdOn,
       p1.pageID,p1.pageName,p1.modifiedOn,
       count(p.*),count(p1.*)
       from mags m
inner join page p
  on m.mjc=p.mjc
inner join page p1
  on m.mjc=p1.mjc
where m.mgc='ABC'
  and p.published=1 
  and p1.published=0
group by 
  m.mjc,m.name,
  p.pageID,p.pageName,
  p.createdOn,p1.pageID,p1.pageName,p1.modifiedOn
order by p.createdOn desc,p1.modifiedOn desc  

我认为您也可以使用max()来转到上一个modifiedOncreatedOn 而不是使用两个查询。

希望它有助于升技