2016-12-01 16 views
2

Я пытаюсь создать задание USQL и определить свои столбцы из CSV, из которых они будут извлекаться, однако у меня всегда возникают проблемы в части JOIN, потому что столбцы Я совпадаю с другим типом. Это странно, потому что я определил их как один тип. Смотрите скриншот где проблема лежит:Ошибка сборки U-SQL, equijoin имеют разные типы

enter image description here

Вот полный USQL:

@guestCheck = 
    EXTRACT GuestCheckID int, 
      POSCheckGUID Guid, 
      POSCheckNumber int?, 
      OwnerEmployeeID int, 
      CreatedDateTime DateTime?, 
      ClosedDateTime DateTime?, 
      TicketReference string, 
      CheckAmount decimal?, 
      POSTerminalID int, 
      CheckState string, 
      LocationID int?, 
      TableID int?, 
      Covers int?, 
      PostedDateTime DateTime?, 
      OrderChannelID int?, 
      MealPeriodID int?, 
      RVCLocationID int?, 
      ReopenedTerminalID int?, 
      ReopenedEmployeeID int?, 
      ReopenedDateTime DateTime?, 
      ClosedBusDate int?, 
      PostedBusDate int?, 
      BusHour byte?, 
      TaxExempt bool?, 
      TaxExemptReference string 
    FROM "/GuestCheck/GuestCheck-incomplete.csv" 
    USING Extractors.Csv(); 

@guestCheckAncillaryAmount = 
    EXTRACT CheckAncillaryAmountID int, 
      GuestCheckID int, 
      GuestCheckItemID int?, 
      AncillaryAmountTypeID int, 
      Amount decimal, 
      FirstDetail int?, 
      LastDetail int?, 
      IsReturn bool?, 
      ReturnReasonID int?, 
      AncillaryReasonID int?, 
      AncillaryNote string, 
      ClosedBusDate int?, 
      PostedBusDate int?, 
      BusHour byte?, 
      LocationID int?, 
      RVCLocationID int?, 
      IsDelisted bool?, 
      Exempted bool? 
    FROM "/GuestCheck/GuestCheckAncillaryAmount.csv" 
    USING Extractors.Csv(); 

@ancillaryAmountType = 
    EXTRACT AncillaryAmountTypeID int, 
      AncillaryAmountCategoryID int, 
      CustomerID int, 
      CheckTitle string, 
      ReportTitle string, 
      Percentage decimal, 
      FixedAmount decimal, 
      IncludeOnCheck bool, 
      AutoCalculate bool, 
      StoreAtCheckLevel bool?, 
      DateTimeModified DateTime?, 
      CheckTitleToken Guid?, 
      ReportTitleToken Guid?, 
      DeletedFlag bool, 
      MaxUsageQty int?, 
      ApplyToBasePriceOnly bool?, 
      Exclusive bool, 
      IsItem bool, 
      MinValue decimal, 
      MaxValue decimal, 
      ItemGroupID int?, 
      LocationID int, 
      ApplicationOrder int?, 
      RequiresReason bool, 
      Exemptable bool? 
    FROM "/GuestCheck/AncillaryAmountType.csv" 
    USING Extractors.Csv(); 

@read = 
    SELECT t.POSCheckGUID, 
      t.POSCheckNumber, 
      t.CheckAmount, 
      aat.AncillaryAmountTypeID, 
      aat.CheckTitle, 
      gcd.Amount 
    FROM @guestCheck AS t   
     LEFT JOIN 
      @guestCheckAncillaryAmount AS gcd 
     ON t.GuestCheckID == gcd.GuestCheckID 
     LEFT JOIN 
      @ancillaryAmountType AS aat 
     ON gcd.AncillaryAmountTypeID == aat.AncillaryAmountTypeID 
    WHERE aat.AncillaryAmountCategoryID IN(2, 4, 8); 

OUTPUT @read 
TO "/GuestCheckOutput/output.csv" 
USING Outputters.Csv(); 

ответ

1

Действительно, USQL сильно типизированных и int и int? различные типы. Вы должны были бы бросить в промежуточном наборе строк:

@ancillaryAmountType2 = 
SELECT (int?) aat.AncillaryAmountTypeID AS AncillaryAmountTypeID, 
     aat.AncillaryAmountCategoryID, 
     aat.CheckTitle 
FROM @ancillaryAmountType AS aat; 

Или, лучше использовать одномерное моделирование передовой практики, а также избегать NULLABLE «размеры» по причинам, указанным в http://blog.chrisadamson.com/2013/01/avoid-null-in-dimensions.html.

+0

Оцените ответ Alexandre. Тем не менее, AncillaryAmountTypeID в файле guestCheckAncillaryAmount и ancillaryAmountType определяется как int. Итак, почему он говорит, что один является int? когда я никогда не заявлял, что это так. – AnimaSola

2

Это не связана с допустимостью пустых столбцов, как указано в определении EXTRACT таблицы, так как OP показал в своем коде, ни один из объединяемых столбцов определяются как нулевые (т.е. с ?) в EXTRACT определение. Это связано с множественными внешними соединениями и так называемой таблицей нулевой подачи.

Если вы думаете об этом логически, представьте, что вы есть три таблицы, TableA было 3 записи, TableB имеет две записи и TableC имеет одну запись, что-то вроде этого:

Tables

Если вы начинаете с TABLEA и left outer join на tableB вы инстинктивно знаете, что получите три записи, но столбец x будет нулевым для столбца tableB x; это ваша таблица с нулевым потреблением и откуда исходит недействительность.

К счастью, исправление такое же; изменить нулеустойчивость столбца раньше или указать замещенные значения, например -1.

@t3 = 
    SELECT (int?) x AS x, 2 AS a 
    FROM dbo.tmpC; 

// OR 

// Use conditional operator to supply substitute values 
@t3 = 
    SELECT x == null ? -1 : x AS x, 2 AS a 
    FROM dbo.tmpC; 

Однако есть еще одна проблема с вашим конкретным запросом. В большинстве реляционных баз данных добавление предложения WHERE в таблицу в правой части left outer join преобразует соединение в inner join, и в U-SQL оно одинаково. Возможно, вам захочется подумать о реальном результате, который вы пытаетесь получить, и подумайте о переписывании вашего запроса.

HTH