2012-02-23 2 views
0

У меня есть таблицы INFO, конструкция которого, как это значение состояниязапросов присоединиться и оптимизация

id - bigint 
Name - varchar2 
refid - bigint 
status - int 
ExpDate - datetime 
  • может быть 0,1,2,3,4
  • RefID является внешним ключом другой таблицы которые мы будем использовать слишком

Я хочу написать запрос, где все записи должны поступать из этой таблицы со статусом 0, 1, 2, 3, но только 7 последних записей по expdate должны прийти чьи статус равен 4.

Я не могу понять, как мы можем достичь этого в T-SQL.

Пожалуйста, помогите мне или дайте мне предложение, чтобы я мог начать писать его.

Upto я писал

SELECT * 
FROM INFO 
WHERE STATUS IN (0,1,2,3) AND 
     REFID IN (SELECT REFID FROM REFTABLE WHERE REFCHAIN='BMW') 

SELECT TOP 7 
FROM INFO 
WHERE STATUS=4 AND 
     REFID IN(SELECT REFID FROM REFTABLE WHERE REFCHAIN='BMW') 
ORDER BY EXPDATE DESC 

я должен присоединиться к ним ??? как .. предложить, а также запрос

(SELECT REFID FROM REFTABLE WHERE REFCHAIN='BMW') 

приходит в два раза, как оптимизировать это спасибо ..

+0

Хотите оптимизировать запрос или удалить дубликаты записей ? – pavanred

+0

Нет дубликатов записей, потому что 'STATUS' отличается. – coms

+0

Хорошо .. «идет дважды, как оптимизировать его, спасибо ..» заставило меня думать, что могут быть дубликаты записей. – pavanred

ответ

4

Просто UNION ваши 2 текущие запросы вместе (вы должны производную таблицу, чтобы получить TOP хотя)

SELECT ... 
FROM INFO 
WHERE STATUS IN (0,1,2,3) AND 
     REFID IN (SELECT REFID FROM REFTABLE WHERE REFCHAIN='BMW') 
UNION ALL 
SELECT ... 
FROM 
    (
    SELECT TOP 7 ... 
    FROM INFO 
    WHERE STATUS=4 AND 
      REFID IN(SELECT REFID FROM REFTABLE WHERE REFCHAIN='BMW') 
    ORDER BY EXPDATE DESC 
    ) T 

Вы можете получить новые идеи, но это не может быть столь же эффективным:

SELECT * 
FROM 
    (
    SELECT ..., 
     ROW_NUMBER() OVER (ORDER BY EXPDATE DESC) AS rn 
    FROM INFO 
    WHERE REFID IN (SELECT REFID FROM REFTABLE WHERE REFCHAIN='BMW') 
    ) T 
WHERE 
    rn <= 7 OR STATUS <= 4 
+0

Подзапросы эффективны или объединяются? – 1Mayur

+0

Подзапросы: посмотрите, почему http://stackoverflow.com/a/6966259/27535 – gbn

1

Вы хотите оптимизировать это, или вы просто хотите удалить дубликаты записей.

Если вы хотите удалить повторяющиеся записи, то вы можете попробовать использовать

союзных
SELECT * FROM INFO 
INNER JOIN REFTABLE ON INFO.refId = REFTABLE.Id 
WHERE REFCHAIN = 'BMW' AND INFO.status IN (0,1,2,3) 
UNION 
SELECT FROM 
    (
     SELECT TOP 7 FROM INFO 
     INNER JOIN REFTABLE ON INFO.refId = REFTABLE.Id 
     WHERE INFO.status=4 AND REFCHAIN='BMW' 
     ORDER BY EXPDATE DESC 
    ) T 
+0

Обратите внимание, что UNION добавляет служебные данные, которых можно избежать с помощью IN (или EXISTS). Причина: IN/EXISTS - это полусоединение, JOIN - равноудаление. См. Http://stackoverflow.com/a/6966259/27535 – gbn

0

за последние 7 значений в Уре reftabl е и можно использовать этот query--

select * from REFTABLE where REFID not in( select top (select count(*)-7 from info) REFID from REFTABLE)

это было бы лучше, если и может опубликовать структуру таблицы ..

+0

Структура таблицы размещена в q. четко проверить q – 1Mayur

0

ГБНЫ и Pavanred ответов о UNION решить вашу проблему «как присоединиться к этим результатам». Если речь идет о оптимизации, вы можете создать временную таблицу для результатов от выбора. Затем запрос выполняется только один раз.

Но ... Я думаю, что запрос слишком тривиален, чтобы оптимизировать его таким образом.

В любом случае:

SELECT REFID 
INTO #temp1 
FROM REFTABLE WHERE REFCHAIN='BMW' 

И затем использовать это в обоих запросах как то:

WHERE REFID IN (SELECT REFID FROM #temp1) 

Или как это

SELECT ... 
FROM INFO inf 
INNER JOIN #temp1 t ON inf.REFID = t.REFID 
... 
Смежные вопросы