2009-10-24 6 views
2

Я довольно новичок в SQL и, пожалуйста, рассказываю со мной, пока я объясняю это, потому что это довольно сложно объяснить.Ошибка SQL Присоединиться к проблеме

У меня есть 3 таблицы:

Trip Promotion Promotion Cost. 
    1 ---- M 1 --------- M 

Выборочные данные включают в себя:

TripID TripName Date 
XYZ123  Hawaii 09/06/09 
YTU574  Japan  09/09/09 
GHR752  US  11/07/09 


PromotionID TripID Name 
1    XYZ123 Poster 
2    XYZ123 Brochure 
3    GHR752 TV ad 

CostID PromotionID Cost 
    1   1   $50 
    2   1   $100 
    3   1   $120 
    4   3   $2000 
    5   2   $500 

Я пытаюсь построить запрос следующим образом:

TripID  Number of Promotions  Total Cost 
XYZ123    2     $770 
GHR752    1     $2000 

Что у меня есть это :

SELECT 
     Trip.TripID, Count(Trip.TripID) AS [Number Of Promotions], Sum(PromotionCost.Cost) AS SumOfCost 
FROM 
    Trip 
    INNER JOIN 
     (Promotion 
      INNER JOIN 
      PromotionCost ON Promotion.PromotionID = PromotionCost.PromotionID 
     ) ON Trip.TripID = Promotion.TripID 
GROUP BY 
     Trip.TripID; 

И это дает мне что-то вроде этого:

TripID  Number of Promotions  Total Cost 
XYZ123    4     $770 
GHR752    1     $2000 

я не уверен, почему количество Promotions перепутались, как, что для первого (XYZ123). Кажется, что как-то РЕГИСТРИРУЙТЕСЬ влияет на это, потому что, если я использую это:

SELECT 
     Trip.TripID, Count(Trip.TripID) AS [Number Of Promotions], 
FROM 
     Trip 
     INNER JOIN 
     Promotion ON Trip.TripID = Promotion.TripID 
GROUP BY 
     Trip.TripID; 

Это дает мне правильное количество поощрений, которое только 2.

Любая помощь?

ответ

0

Не ответ на ваш вопрос, но полезная рекомендация (надеюсь): преобразуйте свой запрос в представление с помощью визуального конструктора SQL Server Management Studio и изучите сгенерированный код SQL. Вам не нужно фактически хранить и использовать сгенерированное представление, но это хороший способ обучения на примере. Я делаю это всякий раз, когда я боюсь сложного запроса.

EDIT. Позор мне, я читаю теги: вопрос связан с MS-Access, а не с SQL Server. Во всяком случае, я думаю, что мой совет по-прежнему действителен, поскольку концептуальное обучение вызывает беспокойство, поскольку синтаксис SQL аналогичен.

+0

Извините, я действительно новичок в этом, но как мне это сделать? –

+0

Вам необходимо установить SQL Server Express (убедитесь, что вы также установили SQL Server Management Studio), затем создайте новую базу данных, создайте нужные вам таблицы и, наконец, создайте представление. Посмотрите здесь: http://msdn.microsoft.com/en-us/library/bb934498.aspx – Konamiman

1

Вы можете попытаться компенсировать повторяющиеся строки Promotion с помощью COUNT(DISTINCT):

SELECT Trip.TripID, Count(DISTINCT Promotion.PromotionID) AS [Number Of Promotions], 
    Sum(PromotionCost.Cost) AS SumOfCost 
FROM Trip INNER JOIN Promotion ON Trip.TripID = Promotion.TripID 
INNER JOIN PromotionCost ON Promotion.PromotionID = PromotionCost.PromotionID 
GROUP BY Trip.TripID; 

Что происходит в том, что по умолчанию, COUNT() подсчитывает строки, полученные после того, как все соединения были сделаны. Для TripID XYZ123 есть четыре рекламные расходы, поэтому четыре строки, хотя TripId происходит несколько раз среди этих четырех строк.

легче визуализировать, если вы попытаетесь аналогичный запрос без GROUP BY:

SELECT Trip.TripID, Promotion.PromotionID, PromotionCost.Cost 
FROM Trip INNER JOIN Promotion ON Trip.TripID = Promotion.TripID 
INNER JOIN PromotionCost ON Promotion.PromotionID = PromotionCost.PromotionID; 

Вы увидите четыре строки для XYZ123 (с повторяющимися значениями PromotionID), и одну строку для GHR752.


Re отмечает, что MS Access не поддерживает COUNT(DISTINCT): если это так, то вы не должны делать это в одном запросе.Сделайте это в двух запросах:

SELECT Trip.TripID, SUM(PromotionCost.Cost) AS SumOfCost 
FROM Trip INNER JOIN Promotion ON Trip.TripID = Promotion.TripID 
INNER JOIN PromotionCost ON Promotion.PromotionID = PromotionCost.PromotionID 
GROUP BY Trip.TripID; 

SELECT Trip.TripID, Count(Promotion.PromotionID) AS [Number Of Promotions] 
FROM Trip INNER JOIN Promotion ON Trip.TripID = Promotion.TripID 
GROUP BY Trip.TripID; 

Альтернативой является очень запутанным решением с использованием подзапросов, описанное в этой статье в Microsoft:

http://blogs.msdn.com/access/archive/2007/09/19/writing-a-count-distinct-query-in-access.aspx

+0

Можете ли вы ВЫБРАТЬ COUNT (DISTINCT) в мс доступ? –

+0

это дает синтаксическую ошибку (отсутствующий оператор) в выражении запроса «Count (DISTINCT Promotion.PromotionID)» –

+0

Нет COUNT (DISTINCT) в доступе мс –

2

Вы можете сложить стоимость для каждой акции в подзапрос. Таким образом, вы получаете только одну строку для каждой рекламы, а COUNT работает, чтобы рассчитать количество рекламных акций за поездку. Например:

select 
    t.TripId 
, count(p.PromotionId) as [Number of Promotions] 
, sum(pc.PromotionCost) as [Total Cost] 
from trip t 
left join promotions p on p.TripId = t.TripId 
left join (
    select 
     PromotionId 
    , PromotionCost = sum(cost) 
    from Promotions 
    group by PromotionId 
) pc on pc.PromotionId = p.PromotionId 
group by t.TripId 

В случае MS Access не позволяет подзапросов, вы можете хранить подзапрос в представлении, и присоединиться к по этому вопросу.

+0

Эй, у нас практически такой же стиль кодирования! Я этого раньше не видел. Кроме того, вы отступы w/4 пробела, где я предпочитаю 2. –

+2

Jet/ACE поддерживает производные подзапросы таблиц, но вы можете использовать только стандартный() синтаксис, если вы используете так называемый режим SQL 93. Если вы используете стандартный режим Jet/ACE SQL 89, вам нужно использовать странный диалект, который использует квадратные скобки, а закрывающий, требующий периода после него, например «[SELECT * FROM MyTable]. Как DerivedTable». Это вызывает проблемы, если ваша строка SQL требует квадратных скобок (потому что вы были глупы и назвали ваши поля зарезервированными словами или включали пробелы или странные символы в именах полей). –

Смежные вопросы