Как я могу присоединиться к этим 3 столам - PullRequest
2 голосов
/ 24 октября 2009

У меня есть 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

Я не уверен, почему Количество продвижений так запутано для первого (XYZ123) Кажется, что как-то JOIN влияет на это, потому что, если я использую это:

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.

Ответы [ 3 ]

2 голосов
/ 24 октября 2009

Вы можете сложить стоимость каждой акции в подзапросе. Таким образом, вы получаете только одну строку для каждой рекламной акции, и 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 не разрешает подзапросы, вы можете сохранить подзапрос в представлении и присоединиться к нему.

1 голос
/ 24 октября 2009

Вы можете попытаться компенсировать повторяющиеся строки Акции, используя 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.


Повторно комментирует, что 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 голосов
/ 24 октября 2009

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

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

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