2017-10-09 110 views
0

有人能指出我在做什麼錯在這裏?SQL左連接表現奇怪

我有時間戳的數據表:

CREATE TABLE data_record (
    id UUID, 
    t TIMESTAMP, 
    d INTEGER, 
    PRIMARY KEY(id, t) 
); 

我已經從該表中的一些項目得到了一些數據,現在我試圖創建一個批處理過程中保持一個項目中,數據值(d)是其他項目的總和。首先,我試圖插入行的彙總項目在其他項目具有行中的所有時間戳:

WITH source_ids AS (
    SELECT UNNEST(ARRAY['1e77b896-9e1b-11e7-a0db-f23c91e2b423'::uuid, '7dd37dd0-9e1a-11e7-a0db-f23c91e2b423'::uuid]) 
) 
INSERT INTO data_record (id, t) (
    SELECT DISTINCT 'ab3b516e-acd7-11e7-a0db-f23c91e2b423'::uuid, d1.t 
     FROM data_record d1 
    LEFT JOIN data_record d2 
     ON d1.t = d2.t 
     AND d1.id IN (SELECT * FROM source_ids) 
     AND d2.id = 'ab3b516e-acd7-11e7-a0db-f23c91e2b423'::uuid 
     WHERE d2.t IS NULL; 

據我所看到的,應該創建一個ID ab3b516e-acd7-11e7-a0db-f23c91e2b423一排每一個時間戳與source_ids中的任一ID相連。但執行該查詢後,我再這樣做:

WITH source_ids AS (
    SELECT UNNEST(ARRAY['1e77b896-9e1b-11e7-a0db-f23c91e2b423'::uuid, '7dd37dd0-9e1a-11e7-a0db-f23c91e2b423'::uuid]) 
) 
    SELECT COUNT(d1.t) 
    FROM data_record d1 
LEFT JOIN data_record d2 
     ON d1.t = d2.t 
     AND d1.id IN (SELECT * FROM source_ids) 
     AND d2.id = 'ab3b516e-acd7-11e7-a0db-f23c91e2b423' 
    WHERE d2.t IS NULL; 

INSERT查詢受影響的28237行; SELECT查詢返回55561,我認爲它應該返回零。

我想有一些關於AND d1.id IN (SELECT * FROM source_ids),它不工作,因爲它看起來應該,但什麼?

+0

移動'及d1.id IN(SELECT * FROM source_ids) AND d2.id = 'ab3b516e-acd7-11e7-a0db-f23c91e2b423' WHERE d2.t IS NULL;''到WHERE'子句。 – lad2025

回答

2

當使用LEFT JOIN時,第一個表上的過濾器應該在WHERE子句中。 ON子句中的第二個上的過濾器。通常,第二張桌子上的過濾器出現錯誤。你的第一張桌子上有過濾器。

所以:

WITH source_ids AS (
    SELECT UNNEST(ARRAY['1e77b896-9e1b-11e7-a0db-f23c91e2b423'::uuid, '7dd37dd0-9e1a-11e7-a0db-f23c91e2b423'::uuid]) 
) 
INSERT INTO data_record (id, t) (
    SELECT DISTINCT 'ab3b516e-acd7-11e7-a0db-f23c91e2b423'::uuid, d1.t 
    FROM data_record d1 LEFT JOIN data_record 
      d2 
      ON d1.t = d2.t AND 
      d2.id = 'ab3b516e-acd7-11e7-a0db-f23c91e2b423'::uuid 
     WHERE d2.t IS NULL AND d1.id IN (SELECT * FROM source_ids); 

這似乎仍然過於複雜的我。我可能會建議:

WITH . . . 
SELECT DISTINCT 'ab3b516e-acd7-11e7-a0db-f23c91e2b423'::uuid, dr.t 
FROM (SELECT dr.*, 
      COUNT(*) FILTER (WHERE dr.id = 'ab3b516e-acd7-11e7-a0db-f23c91e2b423'::uuid) OVER (PARTITION BY t) as cnt 
     FROM data_record dr 
    ) dr 
WHERE cnt = 0; 

根據如何設置數據和索引,您的原始版本可能會更快。