Оператор SQL UNION не работает - PullRequest
0 голосов
/ 09 июля 2009

Почему это неправильно и как я могу это исправить?

SELECT     PublicationID
FROM         (SELECT DISTINCT pat.PublicationID
                       FROM          dbo.PubAdvTransData AS pat INNER JOIN
                                          dbo.PubAdvertiser AS pa ON pat.AdvTransID =   pa.AdvTransID
                       WHERE      (pat.LastAdDate > '7 / 1 / 2009') AND (pat.PublicationID = 29171)) AS table1
UNION
SELECT     PublicationAreaBuy.AreaBuyID AS PublicationID
FROM         PublicationAreaBuy INNER JOIN
                      table1 AS table1_1 ON table1.publicationID =     PublicationAreaBuy.PublicationID

Ошибка в том, что таблица1 является недопустимым объектом.

Спасибо.

Ответы [ 5 ]

7 голосов
/ 09 июля 2009

У вас есть проблема с областью видимости. Союз объединяет два отдельных запроса. Так что если вы разделяете ваши запросы:

SELECT PublicationID
FROM ( SELECT DISTINCT pat.PublicationID
       FROM dbo.PubAdvTransData AS pat 
       INNER JOIN dbo.PubAdvertiser AS pa 
         ON pat.AdvTransID =   pa.AdvTransID
       WHERE (pat.LastAdDate > '7 / 1 / 2009') AND (pat.PublicationID = 29171)
     ) AS table1



SELECT PublicationAreaBuy.AreaBuyID AS PublicationID
FROM PublicationAreaBuy 
INNER JOIN table1 AS table1_1 
  ON table1.publicationID = PublicationAreaBuy.PublicationID

Вы можете видеть, что во втором запросе нет такой вещи как table1. Есть несколько других способов выполнить то, что вы пытаетесь сделать:

  • дублировать подзапрос (некрасиво)
  • использовать общее табличное выражение (только если это T-SQL)
  • использовать #teorary @table (опять же, я знаю, как это сделать только в T-SQL)

Если бы мы дублировали подзапрос, это выглядело бы так. Однако верхний запрос не имеет условий, поэтому он не должен быть подзапросом:

SELECT DISTINCT pat.PublicationID
FROM dbo.PubAdvTransData AS pat 
INNER JOIN dbo.PubAdvertiser AS pa 
   ON pat.AdvTransID =   pa.AdvTransID
WHERE (pat.LastAdDate > '7 / 1 / 2009') AND (pat.PublicationID = 29171)


UNION

SELECT PublicationAreaBuy.AreaBuyID AS PublicationID
FROM PublicationAreaBuy 
INNER JOIN ( SELECT DISTINCT pat.PublicationID
       FROM dbo.PubAdvTransData AS pat 
       INNER JOIN dbo.PubAdvertiser AS pa 
         ON pat.AdvTransID =   pa.AdvTransID
       WHERE (pat.LastAdDate > '7 / 1 / 2009') AND (pat.PublicationID = 29171)
     ) AS table1 
  ON table1.publicationID = PublicationAreaBuy.PublicationID
1 голос
/ 09 июля 2009

Вы можете использовать временную таблицу, но я чувствую, что может быть лучший способ в целом. Не зная вашей схемы БД или того, чего вы пытаетесь достичь, трудно рекомендовать что-либо еще.

CREATE TABLE #temp
(
    PublicationID int
)

SELECT DISTINCT INTO #temp pat.PublicationID
                  FROM dbo.PubAdvTransData AS pat 
                  INNER JOIN dbo.PubAdvertiser AS pa ON pat.AdvTransID = pa.AdvTransID
                  WHERE (pat.LastAdDate > '7 / 1 / 2009') AND (pat.PublicationID = 29171)

    SELECT PublicationID
    FROM   #temp
    UNION
    SELECT PublicationAreaBuy.AreaBuyID AS PublicationID
    FROM   PublicationAreaBuy 
    INNER JOIN #temp As Table1 ON Table1.PublicationID = PublicationAreaBuy.PublicationID

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я набрал это вручную, поэтому проверьте синтаксические ошибки перед запуском.

1 голос
/ 09 июля 2009

AFAIK, вы не можете ссылаться на один запрос из другого. Два запроса, которые вы объединяете, должны быть отдельными и отличными.

Когда вы думаете об этом, это имеет смысл, поскольку единственное, что на самом деле делает объединение, - это последовательно объединяет выходные данные двух запросов.

1 голос
/ 09 июля 2009

Хорошо .. Это.

Два оператора выбора отличаются друг от друга, даже если результаты объединены объединением.

Какой сервер SQL вы используете, включая версию?

0 голосов
/ 09 июля 2009

Попробуйте использовать CTE вместо первого запроса

WITH MyCTE AS 
(
    SELECT DISTINCT pat.PublicationID
    FROM   dbo.PubAdvTransData AS pat 
        INNER JOIN dbo.PubAdvertiser AS pa ON pat.AdvTransID = pa.AdvTransID
    WHERE (pat.LastAdDate > '7 / 1 / 2009') AND (pat.PublicationID = 29171)
)
SELECT PublicationAreaBuy.AreaBuyID AS PublicationID
FROM   PublicationAreaBuy 
    INNER JOIN MyCTE ON MyCTE.publicationID = PublicationAreaBuy.PublicationID 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...