2017-08-27 64 views
1

我需要一些查詢簡化幫助(想避免重複等)PostgreSQL的工時簡化查詢

http://www.sqlfiddle.com/#!17/3607d/1/0

我們有2個對象:

  • working hours定義:mon_frommon_totue_from ...;如果值是null然後不工作與它的nametimezoneworking_hours_id

需要簡化認定,如果該辦公室的工作現在一個查詢,如果辦公室沒有工作規定的那一天

  • office指定小時,然後全天候開放。使用子查詢,而不是橫向

    SELECT 
    name, 
        (CURRENT_TIMESTAMP::time AT TIME ZONE timezone)::time, 
    (workinghours.id IS NULL) OR ((
    ((CURRENT_TIMESTAMP::time AT TIME ZONE timezone)::time BETWEEN mon_from AND mon_to 
    AND EXTRACT(isodow FROM CURRENT_TIMESTAMP AT TIME ZONE timezone) = 1) OR 
    ((CURRENT_TIMESTAMP::time AT TIME ZONE timezone)::time BETWEEN tue_from AND tue_to 
    AND EXTRACT(isodow FROM CURRENT_TIMESTAMP AT TIME ZONE timezone) = 2) OR 
    ((CURRENT_TIMESTAMP::time AT TIME ZONE timezone)::time BETWEEN wed_from AND wed_to 
    AND EXTRACT(isodow FROM CURRENT_TIMESTAMP AT TIME ZONE timezone) = 3) OR 
    ((CURRENT_TIMESTAMP::time AT TIME ZONE timezone)::time BETWEEN thu_from AND thu_to 
    AND EXTRACT(isodow FROM CURRENT_TIMESTAMP AT TIME ZONE timezone) = 4) OR 
    ((CURRENT_TIMESTAMP::time AT TIME ZONE timezone)::time BETWEEN fri_from AND fri_to 
    AND EXTRACT(isodow FROM CURRENT_TIMESTAMP AT TIME ZONE timezone) = 5) OR 
    ((CURRENT_TIMESTAMP::time AT TIME ZONE timezone)::time BETWEEN sat_from AND sat_to 
    AND EXTRACT(isodow FROM CURRENT_TIMESTAMP AT TIME ZONE timezone) = 6) OR 
    ((CURRENT_TIMESTAMP::time AT TIME ZONE timezone)::time BETWEEN sun_from AND sun_to 
    AND EXTRACT(isodow FROM CURRENT_TIMESTAMP AT TIME ZONE timezone) = 7) 
    ) IS True) AS in_workinghours 
    FROM office 
    LEFT JOIN workinghours ON (workinghours.id = office.workinghours_id) 
    
  • +1

    '(CURRENT_TIMESTAMP ::時間AT TIME ZONE時區):: time'可以簡化爲'(CURRENT_TIMESTAMP AT TIME ZONE時區)::時間。 – markusk

    回答

    3
    SELECT 
        name, 
        today_time, 
        (workinghours.id IS NULL) OR (today_time BETWEEN today_wtime[1] AND today_wtime[2]) AS in_workinghours 
    FROM office 
    LEFT JOIN workinghours ON (workinghours.id = office.workinghours_id) 
    CROSS JOIN LATERAL (
        SELECT 
        (CURRENT_TIMESTAMP::time AT TIME ZONE timezone)::time AS today_time, 
        CASE EXTRACT(isodow FROM CURRENT_TIMESTAMP AT TIME ZONE timezone) 
         WHEN 1 THEN ARRAY[mon_from, mon_to] 
         WHEN 2 THEN ARRAY[tue_from, tue_to] 
         WHEN 3 THEN ARRAY[wed_from, wed_to] 
         WHEN 4 THEN ARRAY[thu_from, thu_to] 
         WHEN 5 THEN ARRAY[fri_from, fri_to] 
         WHEN 6 THEN ARRAY[sat_from, sat_to] 
         WHEN 7 THEN ARRAY[sun_from, sun_to] 
        END AS today_wtime) as wtime 
    
    2
    變異

    聯接和數組:

    SELECT 
        name, 
        ts::time time_at_office, 
        (workinghours_id IS NULL) OR 
        (CASE EXTRACT(ISODOW FROM ts) 
        WHEN 1 THEN ts::time BETWEEN mon_from AND mon_to 
        WHEN 2 THEN ts::time BETWEEN tue_from AND tue_to 
        WHEN 3 THEN ts::time BETWEEN wed_from AND wed_to 
        WHEN 4 THEN ts::time BETWEEN thu_from AND thu_to 
        WHEN 5 THEN ts::time BETWEEN fri_from AND fri_to 
        WHEN 6 THEN ts::time BETWEEN sat_from AND sat_to 
        WHEN 7 THEN ts::time BETWEEN sun_from AND sun_to 
        END) AS in_workinghours 
    FROM 
        (SELECT 
        *, 
        CURRENT_TIMESTAMP AT TIME ZONE timezone AS ts 
        FROM office 
        LEFT JOIN workinghours ON (workinghours.id = office.workinghours_id)) owh