복붙노트

[SQL] 어떻게 SQL 쿼리에서 처음이자 마지막 기록을 얻으려면?

SQL

어떻게 SQL 쿼리에서 처음이자 마지막 기록을 얻으려면?

내가 PostgreSQL을의 테이블을 가지고, 나는 열 중 하나에 의해 정렬 된 여러 행을 반환하는 몇 가지 조건과 그것에 쿼리를 실행합니다. 일반적으로 그것입니다 :

SELECT <some columns> 
FROM mytable
<maybe some joins here>
WHERE <various conditions>
ORDER BY date DESC

지금은 제이 쿼리에서 마지막 행을 얻기에만 관심이 있어요. 내 응용 프로그램 내부, 외부 DB의 그들을 얻을 수있다 (이것은 내가 실제로 할 것입니다)하지만, 더 나은 성능을 위해 내가 데이터베이스에서 실제로에 관심 만이 기록을 얻을해야 궁금했다.

만약 그렇다면, 어떻게 내 쿼리를 수정합니까?

해결법

  1. ==============================

    1.[주의해야 할 점은 : 그것을 할 수있는 가장 효율적인 방법되지 않을 수 있습니다]

    [주의해야 할 점은 : 그것을 할 수있는 가장 효율적인 방법되지 않을 수 있습니다]

    (SELECT <some columns>
    FROM mytable
    <maybe some joins here>
    WHERE <various conditions>
    ORDER BY date DESC
    LIMIT 1)
    
    UNION ALL
    
    (SELECT <some columns>
    FROM mytable
    <maybe some joins here>
    WHERE <various conditions>
    ORDER BY date ASC    
    LIMIT 1)
    
  2. ==============================

    2.당신은 잠재적으로 두 개의 쿼리하는 것보다 빠를 수, 이것을 시도 할 수 있습니다 :

    당신은 잠재적으로 두 개의 쿼리하는 것보다 빠를 수, 이것을 시도 할 수 있습니다 :

    select <some columns>
    from (
        SELECT <some columns>,
               row_number() over (order by date desc) as rn,
               count(*) over () as total_count
        FROM mytable
        <maybe some joins here>
        WHERE <various conditions>
    ) t
    where rn = 1
       or rn = total_count
    ORDER BY date DESC
    
  3. ==============================

    3.첫 번째 레코드 :

    첫 번째 레코드 :

    SELECT <some columns> FROM mytable
    <maybe some joins here>
    WHERE <various conditions>
    ORDER BY date ASC
    LIMIT 1
    

    마지막 기록 :

    SELECT <some columns> FROM mytable
    <maybe some joins here>
    WHERE <various conditions>
    ORDER BY date DESC
    LIMIT 1
    
  4. ==============================

    4.마지막 레코드 :

    마지막 레코드 :

    SELECT * FROM `aboutus` order by id desc limit 1
    

    첫 번째 레코드 :

    SELECT * FROM `aboutus` order by id asc limit 1
    
  5. ==============================

    5.지금까지 할 일의 모든 노출면에서, 스캔 두 번, 첫 번째 행에 대해 하나의 마지막 행에 대해 하나를 통과해야합니다.

    지금까지 할 일의 모든 노출면에서, 스캔 두 번, 첫 번째 행에 대해 하나의 마지막 행에 대해 하나를 통과해야합니다.

    창 기능 사용 "ROW_NUMBER () OVER (...)"플러스 "쿼리", 당신은 한 번만 스캔하고 두 항목을 얻을 수 있습니다.

    창 기능 : https://www.postgresql.org/docs/9.6/static/functions-window.html

    함께 쿼리 : https://www.postgresql.org/docs/9.6/static/queries-with.html

    예:

    WITH scan_plan AS (
    SELECT
        <some columns>,
        ROW_NUMBER() OVER (ORDER BY date DESC) AS first_row, /*It's logical required to be the same as major query*/
        ROW_NUMBER() OVER (ORDER BY date ASC) AS last_row /*It's rigth, needs to be the inverse*/
    FROM mytable
    <maybe some joins here>
    WHERE <various conditions>
    ORDER BY date DESC)
    
    SELECT
        <some columns>
    FROM scan_plan
    WHERE scan_plan.first_row = 1 OR scan_plan.last_row = 1;
    

    그 길에 당신은 관계, filtrations 및 데이터 조작 한 번만 할 것입니다.

    일부는 두 가지에 ANALYZE EXPLAIN보십시오.

  6. ==============================

    6.

    SELECT <rows> FROM TABLE_NAME WHERE ROWID=(SELECT MIN(ROWID) FROM TABLE_NAME) 
    UNION
    SELECT <rows> FROM TABLE_NAME WHERE ROWID=(SELECT MAX(ROWID) FROM TABLE_NAME)
    

    또는

    SELECT * FROM TABLE_NAME WHERE ROWID=(SELECT MIN(ROWID) FROM TABLE_NAME) 
                                OR ROWID=(SELECT MAX(ROWID) FROM TABLE_NAME)
    
  7. ==============================

    7.

    select *
    from {Table_Name}
    where {x_column_name}=(
        select d.{x_column_name} 
        from (
            select rownum as rno,{x_column_name}
            from {Table_Name})d
            where d.rno=(
                select count(*)
                from {Table_Name}));
    
  8. ==============================

    8.

    -- Create a function that always returns the first non-NULL item
    CREATE OR REPLACE FUNCTION public.first_agg ( anyelement, anyelement )
    RETURNS anyelement LANGUAGE SQL IMMUTABLE STRICT AS $$
            SELECT $1;
    $$;
    
    
    -- And then wrap an aggregate around it
    CREATE AGGREGATE public.FIRST (
            sfunc    = public.first_agg,
            basetype = anyelement,
            stype    = anyelement
    );
    
    -- Create a function that always returns the last non-NULL item
    CREATE OR REPLACE FUNCTION public.last_agg ( anyelement, anyelement )
    RETURNS anyelement LANGUAGE SQL IMMUTABLE STRICT AS $$
            SELECT $2;
    $$;
    
    -- And then wrap an aggregate around it
    CREATE AGGREGATE public.LAST (
            sfunc    = public.last_agg,
            basetype = anyelement,
            stype    = anyelement
    );
    

    여기에서있어 : https://wiki.postgresql.org/wiki/First/last_(aggregate)

  9. ==============================

    9.어떤 경우에는 - 때 많은하지 열 - 유용한 윈도우 기능 FIRST_VALUE () 및 LAST_VALUE ().

    어떤 경우에는 - 때 많은하지 열 - 유용한 윈도우 기능 FIRST_VALUE () 및 LAST_VALUE ().

     SELECT
        FIRST_VALUE(timestamp) over (ORDER BY timestamp ASC) as created_dt,
        LAST_VALUE(timestamp) over (ORDER BY timestamp ASC) as last_update_dt,
        LAST_VALUE(action) over (ORDER BY timestamp ASC) as last_action
    FROM events
    

    한 번만이 쿼리 정렬 데이터입니다.

    그것은 어떤 ID에 의해 처음과 마지막 행을 얻기 위해 사용될 수있다

    SELECT DISTINCT
        order_id,
        FIRST_VALUE(timestamp) over (PARTITION BY order_id ORDER BY timestamp ASC) as created_dt,
        LAST_VALUE(timestamp) over (PARTITION BY order_id ORDER BY timestamp ASC) as last_update_dt,
        LAST_VALUE(action) over (PARTITION BY order_id ORDER BY timestamp ASC) as last_action
    
    FROM events as x
    
  10. ==============================

    10.

    SELECT 
        MIN(Column), MAX(Column), UserId 
    FROM 
        Table_Name
    WHERE 
        (Conditions)
    GROUP BY 
        UserId DESC
    

    또는

    SELECT        
        MAX(Column) 
    FROM            
        TableName
    WHERE        
        (Filter)
    
    UNION ALL
    
    SELECT        
        MIN(Column)
    FROM            
        TableName AS Tablename1
    WHERE        
        (Filter)
    ORDER BY 
        Column
    
  11. ==============================

    11.어떻게 C #에서 DB의 처음과 마지막 기록을 얻을 수 있습니다.

    어떻게 C #에서 DB의 처음과 마지막 기록을 얻을 수 있습니다.

    SELECT TOP 1 * 
      FROM ViewAttendenceReport 
     WHERE EmployeeId = 4 
       AND AttendenceDate >='1/18/2020 00:00:00' 
       AND AttendenceDate <='1/18/2020 23:59:59'
     ORDER BY Intime ASC
     UNION
    SELECT TOP 1 * 
      FROM ViewAttendenceReport 
     WHERE EmployeeId = 4 
       AND AttendenceDate >='1/18/2020 00:00:00' 
       AND AttendenceDate <='1/18/2020 23:59:59' 
     ORDER BY OutTime DESC; 
    
  12. ==============================

    12.이 코드는 동일한를 얻고 쉽게 읽을 생각합니다.

    이 코드는 동일한를 얻고 쉽게 읽을 생각합니다.

    SELECT <some columns> 
    FROM mytable
    <maybe some joins here>
    WHERE date >= (SELECT date from mytable)
    OR date <= (SELECT date from mytable);
    
  13. ==============================

    13.왜 오름차순 제한 1, 내림차순 제한 (1)에 의한 반대, 순서에 따라 순서를 사용하지?

    왜 오름차순 제한 1, 내림차순 제한 (1)에 의한 반대, 순서에 따라 순서를 사용하지?

  14. from https://stackoverflow.com/questions/1485391/how-to-get-first-and-last-record-from-a-sql-query by cc-by-sa and MIT license