1. 程式人生 > 實用技巧 >關於從left join 變換到笛卡爾連線

關於從left join 變換到笛卡爾連線

話不多說 直接上程式碼

select * from(SELECT Datepart(month, start.add_time) AS month,
       Count(DISTINCT( start.id ))     AS count,
       Count(CASE
               WHEN distribution_processing = 215 THEN 1
             END)                      AS gxd_count,
       Count(CASE
               WHEN distribution_processing =
48 THEN 1 END) AS jxz_count, Count(CASE WHEN distribution_processing = 247 THEN 1 END) AS jzy_count, Count(CASE WHEN distribution_processing = 244 THEN 1 END) AS
yxy_count, Count(CASE WHEN distribution_processing = 266 THEN 1 END) AS zry_count, Count(CASE WHEN distribution_processing = 268 THEN 1 END) AS zyf_count, Count(CASE WHEN
Datediff(ss, start.add_time, stop.add_time) > ( CASE WHEN expected.task_timeout_hour_4 != 0 THEN ( expected.task_timeout_hour_4 - 0.5 ) * 3600 WHEN expected.task_timeout_hour_4 = 0 THEN expected.task_timeout_hour_4 * 3600 END )THEN 1 END) AS timeout_count FROM yh_account_record LEFT JOIN yh_account_log AS start ON start.acc_id = yh_account_record.id AND start.state_type_start = 50 AND start.state_type = 4 LEFT JOIN yh_account_log AS stop ON stop.acc_id = yh_account_record.id AND stop.state_type_start = 4 AND stop.state_type = 11 LEFT JOIN yh_account_log AS cancel ON cancel.acc_id = yh_account_record.id AND cancel.state_type_start = 4 AND cancel.state_type = 8 LEFT JOIN yh_exchange_member ON yh_account_record.exc_bro_id = yh_exchange_member.id LEFT JOIN yh_exchange AS expected ON yh_exchange_member.exc_id = expected.id WHERE yh_account_record.distribution_processing is not null AND start.add_time BETWEEN '2020-1-1' AND '2020-12-31' GROUP BY Datepart(month, start.add_time) )as start, (select Datepart(month, cancel.add_time) as month, Count(DISTINCT( cancel.id )) AS invalid_count from yh_account_record LEFT JOIN yh_account_log AS cancel ON cancel.acc_id = yh_account_record.id AND cancel.state_type_start = 4 AND cancel.state_type = 8 WHERE yh_account_record.distribution_processing is not null AND cancel.add_time BETWEEN '2020-1-1' AND '2020-12-31' GROUP BY Datepart(month, cancel.add_time) )as cancel where start.month=cancel.month

上述程式碼是對兩個查詢結果做笛卡爾連線 同時用where語句過濾掉無用資料

SELECT Datepart(month, start.add_time) AS month,
       Count(DISTINCT( start.id ))     AS count,
       Count(CASE
               WHEN distribution_processing = 215 THEN 1
             END)                      AS gxd_count,
       Count(CASE
               WHEN distribution_processing = 48 THEN 1
             END)                      AS jxz_count,
       Count(CASE
               WHEN distribution_processing = 247 THEN 1
             END)                      AS jzy_count,
       Count(CASE
               WHEN distribution_processing = 244 THEN 1
             END)                      AS yxy_count,
       Count(CASE
               WHEN distribution_processing = 266 THEN 1
             END)                      AS zry_count,
       Count(CASE
               WHEN distribution_processing = 268 THEN 1
             END)                      AS zyf_count,
       Count(CASE
               WHEN Datediff(ss, start.add_time, stop.add_time) > ( CASE
                                                                      WHEN expected.task_timeout_hour_4 != 0 THEN ( expected.task_timeout_hour_4 - 0.5 ) * 3600
                                                                      WHEN expected.task_timeout_hour_4 = 0 THEN expected.task_timeout_hour_4 * 3600
                                                                    END )THEN 1
             END)                      AS timeout_count,
       Count(DISTINCT( cancel.id ))    AS invalid_count
FROM   yh_account_record
       LEFT JOIN yh_account_log AS start
              ON start.acc_id = yh_account_record.id
                 AND start.state_type_start = 50
                 AND start.state_type = 4
       LEFT JOIN yh_account_log AS stop
              ON stop.acc_id = yh_account_record.id
                 AND stop.state_type_start = 4
                 AND stop.state_type = 11
       LEFT JOIN yh_account_log AS cancel
              ON cancel.acc_id = yh_account_record.id
                 AND cancel.state_type_start = 4
                 AND cancel.state_type = 8
       LEFT JOIN yh_exchange_member
              ON yh_account_record.exc_bro_id = yh_exchange_member.id
       LEFT JOIN yh_exchange AS expected
              ON yh_exchange_member.exc_id = expected.id
WHERE  yh_account_record.distribution_processing is not null
       AND convert(char(10),start.add_time,23) BETWEEN '2020-1-1' AND '2020-12-31'
GROUP  BY Datepart(month, start.add_time) 

上述程式碼是通過對資料做左連結,同時通過on關鍵字控制連結後的結果集,通過where關鍵字篩選輸出結果。

兩者最大的不同在於,前者的程式碼稍微變長了一點,但是對於條件的作用更加的獨立,直接作用在查詢結果上,比如對於分月統計每月的xx狀態資料以及yy狀態資料,通過左連結的sql語句where 條件只能寫在單一條件上,而使用笛卡爾積的sql語句可以使where 語句獨立作用在自己的個體上。