【问题标题】:Databricks : Equivalent code for SQL queryDatabricks:SQL 查询的等效代码
【发布时间】:2019-09-18 14:18:14
【问题描述】:

我正在寻找查询的等效数据块代码。 我添加了一些示例代码和预期的代码,但特别是我正在 Databricks 中为 query 寻找等效代码。目前我被困在 CROSS APPLY STRING SPLIT 部分。

示例 SQL 数据:

    CREATE TABLE FactTurnover
    (
    ID INT,
    SalesPriceExcl NUMERIC (9,4),
  Discount VARCHAR(100)
  )
 INSERT INTO FactTurnover
 VALUES 
   (1, 100, '10'),
   (2, 39.5877, '58, 12'),
   (3, 100, '50, 10, 15'),
   (4, 100, 'B')

查询:

    ;WITH CTE AS
    (
     SELECT Id, SalesPriceExcl, 
         CASE WHEN value = 'B' THEN 0
         ELSE CAST(value as int) END AS Discount
     From FactTurnover
     CROSS APPLY STRING_SPLIT(Discount, ',')
     )
     SELECT Id,  
       Min(SalesPriceExcl) AS SalesPriceExcludingDiscount,
       EXP(SUM(LOG((100 - Discount) / 100.0))) As TotalDiscount,
       Cast(EXP(SUM(LOG((100 - Discount) / 100.0))) * 
            MIN(SalesPriceExcl) As Numeric(9,2))
        PriceAfterDiscount
     FROM CTE
     GROUP BY ID

预期结果:

| Id | SalesPriceExcludingDiscount |       TotalDiscount | PriceAfterDiscount |

|----|-----------------------------|---------------------|--------------------|

|  1 |                         100 |                 0.9 |                 90 |

|  2 |                     39.5877 | 0.36960000000000004 |              14.63 |

|  3 |                         100 | 0.38250000000000006 |              38.25 |

|  4 |                         100 |                   1 |                100 |

【问题讨论】:

  • 有什么问题? Databricks 支持 SQL,对吗?
  • 是的,但如果您在 Databricks 中使用它,则并非每个命令都能被识别。当您使用 %sql 启动命令时,它无法识别所有功能。交叉申请就是其中之一。
  • @kjmerf 我想只有Spark SQL,所以你不能在里面复制粘贴其他sql方言
  • 确实如此。就是这样。它是我正在寻找的 Spark 等价物。
  • 您需要使用拆分和分解。像discounts.withColumn("SalesPriceExcl",explode(split($"SalesPriceExcl",","))) 这样的东西。这将为数组中的每个值提供一行,它基本上应该替换交叉应用

标签: sql apache-spark-sql databricks azure-databricks


【解决方案1】:

使用SPLIT 将逗号分隔的字符串转换为数组,然后使用LATERAL VIEWEXPLODE 对该数组的元素进行操作。大致等效的语法(包括 CTE)是:

%sql
--SELECT * FROM FactTurnover;

WITH cte AS
(
SELECT *
FROM
  (
  SELECT Id, SalesPriceExcl, SPLIT ( Discount, ',' ) AS discountArray
  FROM FactTurnover
  ) x
  LATERAL VIEW EXPLODE ( discountArray ) x AS xdiscount
)
SELECT 
  Id,
  MIN(SalesPriceExcl) AS SalesPriceExcludingDiscount,
  EXP ( SUM( LOG( ( 100 - xdiscount ) / 100.00 ) ) ) AS TotalDiscount
FROM cte
GROUP BY Id
ORDER BY Id

如果你有勇气,你也可以使用higher order functions 来做到这一点。我在下面包含了两个示例。我会说这些更难调试,您可能应该在性能方面尝试它们,这取决于您对什么感到满意:

%sql
-- Convert Discount text column to array with SPLIT function and filter out value 'B' from the array
;WITH filterB AS (
SELECT *, FILTER ( SPLIT ( Discount, ',' ), x -> x != 'B' ) discountArray
FROM FactTurnover
), cte1 AS (
-- Do initial calcs on array
SELECT 
  Id,
  TRANSFORM ( discountArray, discountArray -> LOG( ( 100 - discountArray ) / 100.00 ) ) discountArray2
FROM filterB
)
SELECT
  Id,
  EXP( AGGREGATE ( discountArray2, CAST( 0 AS DOUBLE ), ( x, y ) -> x + y ) ) AS x
FROM cte1;

-- all in one example
SELECT 
    Id,
    EXP( AGGREGATE( TRANSFORM( FILTER ( SPLIT ( Discount, ',' ), x -> x != 'B' ), y -> LOG( ( 100 - y ) / 100.00 ) ), CAST( 0 AS DOUBLE ), ( z, a ) -> z + a ) )
    AS final
FROM FactTurnover
ORDER BY Id

【讨论】:

    猜你喜欢
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多