Saya memiliki kueri Snowflake SQL yang saya coba jalankan di R melalui koneksi ODBC yang terlihat seperti ini

SET quiet=TRUE;

USE SOMEDATABASE.SOMESCHEMA;

--Select timestamp of last sale per customer
DROP TABLE IF EXISTS sales;
CREATE TEMPORARY TABLE sales(CustomerId VARCHAR(16777216), SaleTS TIMESTAMP_NTZ(9));

INSERT INTO sales
SELECT CustomerId, 
       SaleTS
FROM SALES
WHERE SaleTS>= '2020-11-19 00:00:00'
AND SaleTS <= '2020-11-19 23:59:59.999'
GROUP BY CustomerId;

--Use temp table to get correct row from sales table
SELECT  SUM(SalesDetail.price) as SumPrice
        COUNT(*) as SoldVolume
FROM sales
LEFT JOIN SALES as SalesDetail
    ON Sales.CustomerId = SalesDetail.CustomerId 
    AND sales.SaleTS = SalesDetail.SaleTS 

Meminta Microsoft SQL Server dari R Saya biasanya menyertakan set nocount no; di bagian atas kueri untuk memastikan hanya langkah terakhir yang dikembalikan ke R untuk menghindari kesalahan Actual statement count 6 did not match the desired statement count 1. Kesalahan masuk akal, SQL mengembalikan 6 komponen ketika R mengharapkan 1 (6 satu untuk setiap langkah dalam kueri SQL saya). Di Snowflake tampaknya tidak ada opsi untuk mengatur nocount dengan cara yang sama. Pertanyaan saya adalah bagaimana cara menghindari kesalahan di atas. Adakah yang punya pengalaman menjalankan kueri Snowflake SQL mutli-langkah melalui R? Bagaimana saya bisa membuat R menerima pernyataan terakhir dari koneksi ODBC. Sejauh ini saya sudah mencoba set nocount=TRUE;, set echo=FALSE;, set message=FALSE;, SET quiet=TRUE dll

3
Morgan Ball 20 November 2020, 20:34

1 menjawab

Jawaban Terbaik

Snowflake SQL cukup ekspresif dan kode yang diusulkan dapat disusun sebagai kueri tunggal:

WITH cte AS (
    SELECT CustomerId, MAX(SaleTS) AS SaleTS  -- here agg function is required
    FROM SALES
    WHERE SaleTS>= '2020-11-19 00:00:00'
    AND SaleTS <= '2020-11-19 23:59:59.999'
    GROUP BY CustomerId
)
SELECT  SUM(SalesDetail.price) as SumPrice
        COUNT(*) as SoldVolume
FROM cte
LEFT JOIN SALES as SalesDetail
    ON Sales.CustomerId = SalesDetail.CustomerId 
    AND sales.SaleTS = SalesDetail.SaleTS;

Kueri asli menggunakan nama yang sama untuk tabel dan tabel sementara yang berbeda hanya berdasarkan kasus sales vs SALES, yang rawan kesalahan.

Kedua: database dan skema dapat diatur selama membuat koneksi, jadi tidak perlu skrip di dalam USE. Atau nama yang sepenuhnya memenuhi syarat dapat digunakan dalam skrip.


Saya kira maksud dari kueri adalah sebagai berikut:

WITH cte AS (
  SELECT *
  FROM SOMEDATABASE.SOMESCHEMA.SALES
  WHERE SaleTS BETWEEN '2020-11-19 00:00:00' AND '2020-11-19 23:59:59.999'
  QUALIFY ROW_NUMBER() OVER(PARTITION BY CustomerId ORDER BY SaleTS DESC) = 1
)
SELECT COUNT(*) AS SoldVolume, SUM(price) as SumPrice
FROM cte;

Jika mungkin satu orang memiliki dua entri untuk SaleTS yang sama persis, maka RANK() OVER(...) harus digunakan sebagai gantinya.

3
Lukasz Szozda 23 November 2020, 16:23