【问题标题】:U-SQL build error, equijoin have different typesU-SQL 构建错误,equijoin 有不同的类型
【发布时间】:2016-12-01 13:51:47
【问题描述】:

我正在尝试创建一个 USQL 作业并从要从中检索它们的 CSV 中定义我的列,但是我总是在 JOIN 部分遇到问题,因为我匹配的列属于不同类型。这很奇怪,因为我已将它们定义为同一类型。查看问题所在的屏幕截图:

这是完整的 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();

【问题讨论】:

    标签: sql analytics azure-data-lake u-sql


    【解决方案1】:

    确实,U-SQL 是强类型的,intint? 是不同的类型。您需要强制转换为中间行集:

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

    或者,更好的是,使用维度建模最佳实践,并避免可空的“维度”,原因在 http://blog.chrisadamson.com/2013/01/avoid-null-in-dimensions.html 中所述。

    【讨论】:

    • 感谢亚历山大的回应。但是,guestCheckAncillaryAmount 和 ancillaryAmountType 中的 AncillaryAmountTypeID 都定义为 int。那么为什么说一个是 int 呢?当我从来没有宣布它是那样的时候。
    【解决方案2】:

    这与EXTRACT 表定义中指定的列的可空性无关,因为正如 OP 在其代码中显示的那样,没有一个连接列被指定为空(即?)在EXTRACT 定义中。这与多个外连接和所谓的空值供应表有关。

    如果你从逻辑上考虑,假设你有 3 个表,TableA 有 3 条记录,TableB 有 2 条记录,TableC 有 1 条记录,如下所示:

    如果您从 tableA 和 left outer join 开始到 tableB,您本能地知道您将获得三个记录,但对于 tableB 列 x,列 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-21
      • 1970-01-01
      相关资源
      最近更新 更多