복붙노트

[SQL] 은 IN 값 목록 BY ORDER

SQL

은 IN 값 목록 BY ORDER

나는 의견의 무리를 잡고 PostgreSQL의 8.3에서 간단한의 SQL 쿼리가 있습니다. 나는 WHERE 절에서 IN 구조에 값 정렬 된 목록을 제공합니다 :

SELECT * FROM comments WHERE (comments.id IN (1,3,2,4));

내에서 1,2,3,4와 같은 식별자 될 일이 임의의 순서로 반환 의견.

(1,3,2,4-) : 나는 결과 행이 IN 구조의 목록과 같이 분류 할 수 있습니다. 어떻게 달성하기 위해?

해결법

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

    1.당신은, (PostgreSQL을 8.2에서 소개) VALUES ()로 아주 쉽게 할 수있다 ().

    당신은, (PostgreSQL을 8.2에서 소개) VALUES ()로 아주 쉽게 할 수있다 ().

    구문은 다음과 같이 될 것입니다 :

    select c.*
    from comments c
    join (
      values
        (1,1),
        (3,2),
        (2,3),
        (4,4)
    ) as x (id, ordering) on c.id = x.id
    order by x.ordering
    
  2. ==============================

    2.너무 찾기 어렵고은 확산되어야한다해서이 훨씬 간단 할 수 MySQL의에 있지만, 다른 SQL에서 작동하는지 모르겠어요.

    너무 찾기 어렵고은 확산되어야한다해서이 훨씬 간단 할 수 MySQL의에 있지만, 다른 SQL에서 작동하는지 모르겠어요.

    SELECT * FROM `comments`
    WHERE `comments`.`id` IN ('12','5','3','17')
    ORDER BY FIELD(`comments`.`id`,'12','5','3','17')
    
  3. ==============================

    3.포스트 그레스 9.4 이상에서는이 아마 가장 간단하고 가장 빠른 :

    포스트 그레스 9.4 이상에서는이 아마 가장 간단하고 가장 빠른 :

    SELECT c.*
    FROM   comments c
    JOIN   unnest('{1,3,2,4}'::int[]) WITH ORDINALITY t(id, ord) USING (id)
    ORDER  BY t.ord;
    

    상해:

  4. ==============================

    4.나는이 방법은 더 나은 생각 :

    나는이 방법은 더 나은 생각 :

    SELECT * FROM "comments" WHERE ("comments"."id" IN (1,3,2,4))
        ORDER BY  id=1 DESC, id=3 DESC, id=2 DESC, id=4 DESC
    
  5. ==============================

    5.포스트 그레스 9.4이 조금 짧은 수행 할 수 있습니다 :

    포스트 그레스 9.4이 조금 짧은 수행 할 수 있습니다 :

    select c.*
    from comments c
    join (
      select *
      from unnest(array[43,47,42]) with ordinality
    ) as x (id, ordering) on c.id = x.id
    order by x.ordering;
    

    아니면 파생 테이블없이 컴팩트 비트 :

    select c.*
    from comments c
      join unnest(array[43,47,42]) with ordinality as x (id, ordering) 
        on c.id = x.id
    order by x.ordering
    

    수동으로 할당 할 필요를 제거 / 각 값에 대한 위치를 유지한다.

    포스트 그레스 9.6과 함께이 array_position ()를 사용하여 수행 할 수 있습니다 :

    with x (id_list) as (
      values (array[42,48,43])
    )
    select c.*
    from comments c, x
    where id = any (x.id_list)
    order by array_position(x.id_list, c.id);
    

    열팽창 계수는 값 목록이 한 번만 지정해야합니다 있도록 사용됩니다. 즉 중요하지 않은 경우이도 같이 쓸 수있다 :

    select c.*
    from comments c
    where id in (42,48,43)
    order by array_position(array[42,48,43], c.id);
    
  6. ==============================

    6.포스트 그레스에서 할 수있는 또 다른 방법은 IDX 기능을 사용하는 것입니다.

    포스트 그레스에서 할 수있는 또 다른 방법은 IDX 기능을 사용하는 것입니다.

    SELECT *
    FROM comments
    ORDER BY idx(array[1,3,2,4], comments.id)
    

    여기에 설명 된 바와 같이, 먼저 IDX 함수를 생성하는 것을 잊지 마세요 : http://wiki.postgresql.org/wiki/Array_Index

  7. ==============================

    7.PostgreSQL을에서 :

    PostgreSQL을에서 :

    select *
    from comments
    where id in (1,3,2,4)
    order by position(id::text in '1,3,2,4')
    
  8. ==============================

    8.연구에서이 좀 더 나는이 해결책을 발견 :

    연구에서이 좀 더 나는이 해결책을 발견 :

    SELECT * FROM "comments" WHERE ("comments"."id" IN (1,3,2,4)) 
    ORDER BY CASE "comments"."id"
    WHEN 1 THEN 1
    WHEN 3 THEN 2
    WHEN 2 THEN 3
    WHEN 4 THEN 4
    END
    

    그러나이 오히려 자세한 보인다 대규모 데이터 세트와 성능 문제가있을 수 있습니다. 이 문제에 캔 사람의 의견?

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

    9.(효과적으로 자신의 질문에 대한 응답이 말을하고) 이렇게하려면, 당신은 다음 선택에 추가 열로 사용할 수있는, 당신은 아마 주문 ID의 매핑을 정의하는 추가 "ORDER"테이블이해야한다고 생각하는 당신은 다음에 정렬 할 수 있습니다.

    (효과적으로 자신의 질문에 대한 응답이 말을하고) 이렇게하려면, 당신은 다음 선택에 추가 열로 사용할 수있는, 당신은 아마 주문 ID의 매핑을 정의하는 추가 "ORDER"테이블이해야한다고 생각하는 당신은 다음에 정렬 할 수 있습니다.

    이런 식으로, 당신은 명시 적으로 당신이해야 데이터베이스에서 원하는 순서를 설명합니다.

  10. ==============================

    10.산세 SEQUENCE는 8.4에서만 작동합니다 :

    산세 SEQUENCE는 8.4에서만 작동합니다 :

    select * from comments c
    join 
    (
        select id, row_number() over() as id_sorter  
        from (select unnest(ARRAY[1,3,2,4]) as id) as y
    ) x on x.id = c.id
    order by x.id_sorter
    
  11. ==============================

    11.

    SELECT * FROM "comments" JOIN (
      SELECT 1 as "id",1 as "order" UNION ALL 
      SELECT 3,2 UNION ALL SELECT 2,3 UNION ALL SELECT 4,4
    ) j ON "comments"."id" = j."id" ORDER BY j.ORDER
    

    또는 당신은 좋은 이상 악을 선호하는 경우 :

    SELECT * FROM "comments" WHERE ("comments"."id" IN (1,3,2,4))
    ORDER BY POSITION(','+"comments"."id"+',' IN ',1,3,2,4,')
    
  12. ==============================

    12.나는 나 "SQL가 잘되지 않습니다" "그하지 않는다"라고 다른 포스터에 동의합니다. 당신이 의견의 어떤면을 기준으로 정렬하려면 다음 정렬 기준을 유지하고 일종의 그 값에 의해 테이블 ​​중 하나의 테이블에 또 다른 정수 열을 추가합니다. 예를 들어 "comments.sort의 DESC BY ORDER"당신이 때마다 다음 다른 순서대로 정렬하려면 ... SQL이 경우에 당신을 위해하지 않습니다.

    나는 나 "SQL가 잘되지 않습니다" "그하지 않는다"라고 다른 포스터에 동의합니다. 당신이 의견의 어떤면을 기준으로 정렬하려면 다음 정렬 기준을 유지하고 일종의 그 값에 의해 테이블 ​​중 하나의 테이블에 또 다른 정수 열을 추가합니다. 예를 들어 "comments.sort의 DESC BY ORDER"당신이 때마다 다음 다른 순서대로 정렬하려면 ... SQL이 경우에 당신을 위해하지 않습니다.

  13. ==============================

    13.그리고 여기 또 다른 해결책은의 그 작품과 사용 상수 테이블 (http://www.postgresql.org/docs/8.3/interactive/sql-values.html) :

    그리고 여기 또 다른 해결책은의 그 작품과 사용 상수 테이블 (http://www.postgresql.org/docs/8.3/interactive/sql-values.html) :

    SELECT * FROM comments AS c,
    (VALUES (1,1),(3,2),(2,3),(4,4) ) AS t (ord_id,ord)
    WHERE (c.id IN (1,3,2,4)) AND (c.id = t.ord_id)
    ORDER BY ord
    

    그러나 다시 나는 확실하지이 확대됨이라고 해요.

    지금 답변을 잔뜩 있어요. 나는 승자 인 알 수 있도록 좀 투표와 의견을 얻을 수 있습니다!

    감사합니다 모든 :-)

  14. ==============================

    14.

    create sequence serial start 1;
    
    select * from comments c
    join (select unnest(ARRAY[1,3,2,4]) as id, nextval('serial') as id_sorter) x
    on x.id = c.id
    order by x.id_sorter;
    
    drop sequence serial;
    

    [편집하다]

    unnest 아직 8.3에 내장되지 않은,하지만 당신은 하나를 자신 (모든 *의 아름다움을) 만들 수 있습니다 :

    create function unnest(anyarray) returns setof anyelement
    language sql as
    $$
        select $1[i] from generate_series(array_lower($1,1),array_upper($1,1)) i;
    $$;
    

    기능은 모든 유형에서 작동 할 수있는 :

    select unnest(array['John','Paul','George','Ringo']) as beatle
    select unnest(array[1,3,2,4]) as id
    
  15. ==============================

    15.내가 생각하는 시퀀스를 사용하는 버전을 통해 약간의 개선 :

    내가 생각하는 시퀀스를 사용하는 버전을 통해 약간의 개선 :

    CREATE OR REPLACE FUNCTION in_sort(anyarray, out id anyelement, out ordinal int)
    LANGUAGE SQL AS
    $$
        SELECT $1[i], i FROM generate_series(array_lower($1,1),array_upper($1,1)) i;
    $$;
    
    SELECT 
        * 
    FROM 
        comments c
        INNER JOIN (SELECT * FROM in_sort(ARRAY[1,3,2,4])) AS in_sort
            USING (id)
    ORDER BY in_sort.ordinal;
    
  16. ==============================

    16.

    select * from comments where comments.id in 
    (select unnest(ids) from bbs where id=19795) 
    order by array_position((select ids from bbs where id=19795),comments.id)
    

    여기서, [BBS] IDS라는 필드가 기본 테이블은, 그리고, ID는 comments.id를 저장하는 배열이다.

    PostgreSQL의 9.6 전달

  17. ==============================

    17.이미 무슨 말을했는지에 대한 시각적 인 느낌을 얻을 수 있습니다. 예를 들어, 당신은 몇 가지 작업에 테이블이 :

    이미 무슨 말을했는지에 대한 시각적 인 느낌을 얻을 수 있습니다. 예를 들어, 당신은 몇 가지 작업에 테이블이 :

    SELECT a.id,a.status,a.description FROM minicloud_tasks as a ORDER BY random();
    
     id |   status   |   description    
    ----+------------+------------------
      4 | processing | work on postgres
      6 | deleted    | need some rest
      3 | pending    | garden party
      5 | completed  | work on html
    

    그리고 당신은 그 상태로 작업 목록을 주문합니다. 상태는 문자열 값의 목록입니다 :

    (processing, pending,  completed, deleted)
    

    트릭은 각 상태 값을 정수를 제공하고 목록의 수치를 주문하는 것입니다 :

    SELECT a.id,a.status,a.description FROM minicloud_tasks AS a
      JOIN (
        VALUES ('processing', 1), ('pending', 2), ('completed', 3), ('deleted', 4)
      ) AS b (status, id) ON (a.status = b.status)
      ORDER BY b.id ASC;
    

    어떤 리드에 :

     id |   status   |   description    
    ----+------------+------------------
      4 | processing | work on postgres
      3 | pending    | garden party
      5 | completed  | work on html
      6 | deleted    | need some rest
    

    신용 @ user80168

  18. from https://stackoverflow.com/questions/866465/order-by-the-in-value-list by cc-by-sa and MIT license