SQL Server Query - рассчитывать на одну таблицу дважды - PullRequest
1 голос
/ 23 ноября 2011

Эта проблема посылает меня с ума, хотя по общему признанию я давно не писал SQL.

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

CREATE TABLE [Entities].[Events](
[EventID] [int] IDENTITY(1,1) NOT NULL,
[EventVenueID] [int] NULL,
[EntityID] [int] NOT NULL,
[OrganisationID] [int] NULL,
[Title] [nvarchar](300) NOT NULL,
[DateStart] [datetime] NOT NULL,
[DateFinish] [datetime] NOT NULL,
[Notes] [nvarchar](max) NULL,
[MinimumProviders] [int] NOT NULL,
[MinimumAttendees] [int] NOT NULL,
[ShowCalendar] [bit] NOT NULL,
[CreationDate] [datetime] NOT NULL,
[IsEnabled] [bit] NOT NULL)

CREATE TABLE [Entities].[EventParticipants](
[ParticipantID] [int] IDENTITY(1,1) NOT NULL,
[EventID] [int] NOT NULL,
[PersonID] [int] NOT NULL,
[ParticipantType] [int] NOT NULL,
[ParticipantStatus] [int] NOT NULL,
[AttendanceStatus] [int] NULL)

И запрос:

SELECT
e.EventID,
ev.VenueName,
e.EntityID,
o.Name AS 'Organisation',
e.Title,
e.DateStart,
e.DateFinish,
e.Notes,
e.MinimumProviders,
e.MinimumAttendees,
e.CreationDate,
COUNT(epp.ParticipantID) AS 'ProvidersConfirmed',
COUNT(epa.ParticipantID) AS 'AttendeesConfirmed',
e.IsEnabled
  FROM
Entities.Events e
  LEFT OUTER JOIN
Entities.EventVenues ev
  ON
e.EventVenueID = ev.EventVenueID
  LEFT OUTER JOIN
Entities.Organisations o
  ON
e.OrganisationID = o.OrganisationID
  LEFT OUTER JOIN
Entities.EventParticipants epp
  ON
e.EventID = epp.EventID AND epp.ParticipantType = 1 AND epp.ParticipantStatus = 3
  LEFT OUTER JOIN
Entities.EventParticipants epa
  ON
e.EventID = epa.EventID AND epa.ParticipantType = 2 AND epa.ParticipantStatus = 3
  GROUP BY
e.EventID,
ev.VenueName,
e.EntityID,
o.Name,
e.Title,
e.DateStart,
e.DateFinish,
e.Notes,
e.MinimumProviders,
e.MinimumAttendees,
e.CreationDate,
e.IsEnabled

Счетчик дает странные результаты, например, в таблице EventParticipants у меня есть следующие данные:

Тип участника = 1 (3 записи) Тип участника = 2 (1 запись) Статус участника = 3 (4 записи)

Количество запросов должно возвращаться:

ProvidersConfirmed = 3 AtcondeesConfirmed = 1

Однако, он возвращается

ProvidersConfirmed = 3 AtcondeesConfirmed = 3

Может кто-нибудь помочь?

Ответы [ 3 ]

1 голос
/ 23 ноября 2011

В основном все ваши объединения отбрасывают этот запрос. Когда вы присоединяетесь от Event до EventParticipants Существует одна запись события и три записи EventParticipant, это равняется трем дубликатам eventID в вашем наборе данных. Затем вы присоединитесь к EventParticipants снова. Поскольку вы объединяете 3 ряда в один ряд, результат повторяется 3 раза.

Есть способы урезать результаты, но, вероятно, было бы лучше всего JOIN один раз и выполнить некоторую выборочную математику в вашем агрегате, например:

SELECT
e.EventID,
ev.VenueName,
e.EntityID,
o.Name AS 'Organisation',
e.Title,
e.DateStart,
e.DateFinish,
e.Notes,
e.MinimumProviders,
e.MinimumAttendees,
e.CreationDate,
COUNT(CASE WHEN ep.ParticipantType = 1 THEN 1 ELSE NULL END) AS 'ProvidersConfirmed',
COUNT(CASE WHEN ep.ParticipantType = 2 THEN 1 ELSE NULL END) AS 'AttendeesConfirmed',
e.IsEnabled
  FROM
Entities.Events e
  LEFT OUTER JOIN
Entities.EventVenues ev
  ON
e.EventVenueID = ev.EventVenueID
  LEFT OUTER JOIN
Entities.Organisations o
  ON
e.OrganisationID = o.OrganisationID
  LEFT OUTER JOIN
Entities.EventParticipants epp
  ON
e.EventID = epp.EventID AND epp.ParticipantStatus = 3
  GROUP BY
e.EventID,
ev.VenueName,
e.EntityID,
o.Name,
e.Title,
e.DateStart,
e.DateFinish,
e.Notes,
e.MinimumProviders,
e.MinimumAttendees,
e.CreationDate,
e.IsEnabled

И SQL COUNT отбрасывает все нулевые значения, поэтому он будет считать только уникальные значения.

1 голос
/ 23 ноября 2011

Рассмотрим:

COUNT(DISTINCT epp.ParticipantID) AS 'ProvidersConfirmed',
COUNT(DISTINCT epa.ParticipantID) AS 'AttendeesConfirmed'

Ближе, но это все равно будет считать значения NULL, следовательно ....

COUNT(DISTINCT epp.ParticipantID) 
     - MAX(CASE WHEN epp.ParticipantID IS NULL THEN 1 ELSE 0 END)  
     AS 'ProvidersConfirmed',
COUNT(DISTINCT epa.ParticipantID)
     - MAX(CASE WHEN epa.ParticipantID IS NULL THEN 1 ELSE 0 END)
     AS 'AttendeesConfirmed'
0 голосов
/ 23 ноября 2011

Вы уверены, что вам нужно Left Outer Join

Поскольку Left Outer Join выберет все строки из левой таблицы.Я полагаю, что это проблема, все строки выбираются в одной точке от Участников События.

Вы можете использовать INNER объединение, если использование Outer не является обязательным.

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