• Use CTEs to eliminate subselects and make your code more readable (the view is also eliminated by the first cte):

    WITH cte_tables (zCardNo, zDate, zDatetime1, zChannel_no)

    AS ( SELECT cardno, CONVERT(DATE, datetime1), datetime1, channel_no

    FROM TABLE1

    UNION ALL

    SELECT cardno, CONVERT(DATE, datetime1), datetime1, Action

    FROM TABLE2

    )

    , cte_minmax (aCardNo, aDate, aMinDatetime1, aMaxDatetime1)

    AS (

    SELECT zCardNo, zDate, MIN(zDatetime1), NULL

    FROM cte_tables

    WHERE zChannel_no = 1

    GROUP BY zCardNo, zDate

    UNION ALL

    SELECT zCardNo, zDate, NULL, MAX(zDatetime1)

    FROM cte_tables

    WHERE zChannel_no = 2

    GROUP BY zCardNo, zDate

    )

    SELECT aCardNo AS cardno

    , REPLACE(CONVERT(VarChar(50), aDate, 103),'/','-') AS [date]

    , LEFT(CONVERT(varchar,MAX(aMinDatetime1),108),5) AS intime

    , LEFT(CONVERT(varchar,MAX(aMaxDatetime1),108),5) AS outtime

    FROM cte_minmax

    GROUP BY aCardNo, aDate