Возвращение значений из многих таблиц в виде полей в одном наборе результатов - PullRequest
0 голосов
/ 12 февраля 2012

У меня есть следующий запрос, который возвращает набор результатов, заполненных значениями из другой таблицы:

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 ]

4 голосов
/ 12 февраля 2012

Вы можете несколько оптимизировать свои подзапросы.Эти проекции здесь:

(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

2 голосов
/ 12 февраля 2012

Попробуйте:

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 к предложениям over полей row_number.

1 голос
/ 12 февраля 2012

Я думал, что это будет что-то вроде этого но я не уверен, что это даст вам такие же результаты. Я бы настроил его, если бы увидел результаты, конечно. Но просто в качестве примера:


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() также, чтобы добраться до последних modifiedOn и createdOn вместо двух запросов.

надеюсь, что это поможет abit

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...