복붙노트

[SQL] 가장 최근의 행을 가입 MYSQL?

SQL

가장 최근의 행을 가입 MYSQL?

나는 테이블 고객이 저장합니다 CUSTOMER_ID, 이메일 및 참조가 있습니다. 저장 변화의 역사적 기록이 고객에게 만들어진 것을 추가 테이블 customer_data하는 변경이있을 때 즉 새로운 행이 삽입되어있다.

테이블에 고객 정보를 표시하기 위해, 두 테이블은 그러나 고객 데이터에서 가장 최근의 행이 고객 테이블에 조인해야 가입 할 필요가있다.

너무 한계가와 오프셋, 더 쿼리 페이지 매김되어 복잡 조금 가져옵니다.

어떻게 MySQL과이 작업을 수행 할 수 있습니까? 나는이 곳에서 DISTINCT를 넣어 원하는 것 같아 ...

분에서 쿼리 this- 같다

SELECT *, CONCAT(title,' ',forename,' ',surname) AS name
FROM customer c
INNER JOIN customer_data d on c.customer_id=d.customer_id
WHERE name LIKE '%Smith%' LIMIT 10, 20

또한, 나는 이런 식으로 LIKE와 CONCAT을 사용할 수 있습니다 생각에 바로 무엇입니까?

(나는 INNER 사용에 가입의 잘못된 유형의 수 있습니다 가입 있음을 주셔서 감사합니다. 실제로 차이가 다른 조인 사이에 어떤 단서가 없다. 내가 지금 들여다 갈거야!)

해결법

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

    1.다음을 시도 할 수 있습니다 :

    다음을 시도 할 수 있습니다 :

    SELECT    CONCAT(title, ' ', forename, ' ', surname) AS name
    FROM      customer c
    JOIN      (
                  SELECT    MAX(id) max_id, customer_id 
                  FROM      customer_data 
                  GROUP BY  customer_id
              ) c_max ON (c_max.customer_id = c.customer_id)
    JOIN      customer_data cd ON (cd.id = c_max.max_id)
    WHERE     CONCAT(title, ' ', forename, ' ', surname) LIKE '%Smith%' 
    LIMIT     10, 20;
    

    내부 조인에 대한 조인주의는 동의어입니다.

    테스트 케이스 :

    CREATE TABLE customer (customer_id int);
    CREATE TABLE customer_data (
       id int, 
       customer_id int, 
       title varchar(10),
       forename varchar(10),
       surname varchar(10)
    );
    
    INSERT INTO customer VALUES (1);
    INSERT INTO customer VALUES (2);
    INSERT INTO customer VALUES (3);
    
    INSERT INTO customer_data VALUES (1, 1, 'Mr', 'Bobby', 'Smith');
    INSERT INTO customer_data VALUES (2, 1, 'Mr', 'Bob', 'Smith');
    INSERT INTO customer_data VALUES (3, 2, 'Mr', 'Jane', 'Green');
    INSERT INTO customer_data VALUES (4, 2, 'Miss', 'Jane', 'Green');
    INSERT INTO customer_data VALUES (5, 3, 'Dr', 'Jack', 'Black');
    

    (쿼리 제한없이 WHERE) 결과 :

    SELECT    CONCAT(title, ' ', forename, ' ', surname) AS name
    FROM      customer c
    JOIN      (
                  SELECT    MAX(id) max_id, customer_id 
                  FROM      customer_data 
                  GROUP BY  customer_id
              ) c_max ON (c_max.customer_id = c.customer_id)
    JOIN      customer_data cd ON (cd.id = c_max.max_id);
    
    +-----------------+
    | name            |
    +-----------------+
    | Mr Bob Smith    |
    | Miss Jane Green |
    | Dr Jack Black   |
    +-----------------+
    3 rows in set (0.00 sec)
    
  2. ==============================

    2.당신이 무거운 쿼리로 작업하는 경우, 당신은 더 나은 where 절에서 최신 행에 대한 요청을 이동합니다. 그것은 훨씬 빨리와 외모 청소기입니다.

    당신이 무거운 쿼리로 작업하는 경우, 당신은 더 나은 where 절에서 최신 행에 대한 요청을 이동합니다. 그것은 훨씬 빨리와 외모 청소기입니다.

    SELECT c.*,
    FROM client AS c
    LEFT JOIN client_calling_history AS cch ON cch.client_id = c.client_id
    WHERE
       cch.cchid = (
          SELECT MAX(cchid)
          FROM client_calling_history
          WHERE client_id = c.client_id AND cal_event_id = c.cal_event_id
       )
    
  3. ==============================

    3.고객 데이터의 자동 증가 열을 추정하는 경우라고 할 수있다 :

    고객 데이터의 자동 증가 열을 추정하는 경우라고 할 수있다 :

    SELECT CONCAT(title,' ',forename,' ',surname) AS name *
    FROM customer c
        INNER JOIN customer_data d 
            ON c.customer_id=d.customer_id
    WHERE name LIKE '%Smith%'
        AND d.ID = (
                    Select Max(D2.Id)
                    From customer_data As D2
                    Where D2.customer_id = D.customer_id
                    )
    LIMIT 10, 20
    
  4. ==============================

    4.MySQL은 (이전 5.0 틱)의 이전 버전에서 작동한다 누군가를 위해 당신은 쿼리 이러한 유형의 하위 쿼리를 할 수 없습니다. 여기에 내가 할 수 있었던 솔루션입니다 그리고 잘 작동하는 것 같았다.

    MySQL은 (이전 5.0 틱)의 이전 버전에서 작동한다 누군가를 위해 당신은 쿼리 이러한 유형의 하위 쿼리를 할 수 없습니다. 여기에 내가 할 수 있었던 솔루션입니다 그리고 잘 작동하는 것 같았다.

    SELECT MAX(d.id), d2.*, CONCAT(title,' ',forename,' ',surname) AS name
    FROM customer AS c 
    LEFT JOIN customer_data as d ON c.customer_id=d.customer_id 
    LEFT JOIN customer_data as d2 ON d.id=d2.id
    WHERE CONCAT(title, ' ', forename, ' ', surname) LIKE '%Smith%'
    GROUP BY c.customer_id LIMIT 10, 20;
    

    기본적으로이 후 최대 아이디 이룰 데이터 테이블에 가입 고객에 합류 데이터 테이블의 최대 ID를 찾는 것입니다. 그룹의 최대를 선택하면 ID가 데이터 일치의 나머지는 자체에 다시 가입하지 않는 것을 보장하지 않기 때문이다.

    나는 MySQL의 최신 버전에서이 테스트를하지 않은 그러나 4.0.30에서 작동합니다.

  5. ==============================

    5.이 질문은 오래 알고 있지만, 그것은 지난 몇 년 동안 많은 관심을 가지고와 나는 비슷한 경우에 다른 사람을 도울 수있는 개념이없는 것 같아요. 나는 완벽을 위해 여기에 추가하고있다.

    이 질문은 오래 알고 있지만, 그것은 지난 몇 년 동안 많은 관심을 가지고와 나는 비슷한 경우에 다른 사람을 도울 수있는 개념이없는 것 같아요. 나는 완벽을 위해 여기에 추가하고있다.

    당신이 당신의 원본 데이터베이스의 스키마를 수정할 수없는 경우 좋은 답변을 많이 제공되었고, 잘 문제를 해결.

    당신은, 그러나, 스키마를 수정할 수있는 경우에, 나는이 고객에 대한 최신 customer_data 레코드의 ID를 보유하고 고객 테이블에 필드를 추가 권합니다 :

    CREATE TABLE customer (
      id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
      current_data_id INT UNSIGNED NULL DEFAULT NULL
    );
    
    CREATE TABLE customer_data (
       id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
       customer_id INT UNSIGNED NOT NULL, 
       title VARCHAR(10) NOT NULL,
       forename VARCHAR(10) NOT NULL,
       surname VARCHAR(10) NOT NULL
    );
    

    쿼리는 될 수있는 한 빨리 간단하고 있습니다 :

    SELECT c.*, d.title, d.forename, d.surname
    FROM customer c
    INNER JOIN customer_data d on d.id = c.current_data_id
    WHERE ...;
    

    만들거나 고객을 업데이트 할 때의 단점은 여분의 복잡성이다.

    당신이 고객을 업데이트 할 때마다, 당신은 customer_data 테이블에 새로운 레코드를 삽입하고, 고객 레코드를 업데이트합니다.

    INSERT INTO customer_data (customer_id, title, forename, surname) VALUES(2, 'Mr', 'John', 'Smith');
    UPDATE customer SET current_data_id = LAST_INSERT_ID() WHERE id = 2;
    

    고객 만들기 다음 같은 문장을 실행, 고객 항목을 삽입의 문제입니다 :

    INSERT INTO customer () VALUES ();
    
    SET @customer_id = LAST_INSERT_ID();
    INSERT INTO customer_data (customer_id, title, forename, surname) VALUES(@customer_id, 'Mr', 'John', 'Smith');
    UPDATE customer SET current_data_id = LAST_INSERT_ID() WHERE id = @customer_id;
    

    작성을위한 여분의 복잡성 / 고객을 업데이트하면 무시 무시한 될 수도 있지만 쉽게 트리거와 자동화 할 수 있습니다.

    당신이 ORM을 사용하는 경우 마지막으로,이 관리하기 정말 쉽게 할 수 있습니다. ORM은 값을 삽입 ID를 갱신하고, 자동으로 두 테이블을 조인 돌볼 수 있습니다.

    다음은 변경 가능한 고객 모델의 모습 방법입니다

    class Customer
    {
        private int id;
        private CustomerData currentData;
    
        public Customer(String title, String forename, String surname)
        {
            this.update(title, forename, surname);
        }
    
        public void update(String title, String forename, String surname)
        {
            this.currentData = new CustomerData(this, title, forename, surname);
        }
    
        public String getTitle()
        {
            return this.currentData.getTitle();
        }
    
        public String getForename()
        {
            return this.currentData.getForename();
        }
    
        public String getSurname()
        {
            return this.currentData.getSurname();
        }
    }
    

    그리고 당신의 불변 CustomerData 모델, 즉 단지 게터를 포함 :

    class CustomerData
    {
        private int id;
        private Customer customer;
        private String title;
        private String forename;
        private String surname;
    
        public CustomerData(Customer customer, String title, String forename, String surname)
        {
            this.customer = customer;
            this.title    = title;
            this.forename = forename;
            this.surname  = surname;
        }
    
        public String getTitle()
        {
            return this.title;
        }
    
        public String getForename()
        {
            return this.forename;
        }
    
        public String getSurname()
        {
            return this.surname;
        }
    }
    
  6. ==============================

    6.

    SELECT CONCAT(title,' ',forename,' ',surname) AS name * FROM customer c 
    INNER JOIN customer_data d on c.id=d.customer_id WHERE name LIKE '%Smith%' 
    

    난 당신이 변경할 필요가 있다고 생각 c.customer_id에 c.id

    다른 업데이트 테이블 구조

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

    7.또한이 작업을 수행 할 수 있습니다

    또한이 작업을 수행 할 수 있습니다

    SELECT    CONCAT(title, ' ', forename, ' ', surname) AS name
    FROM      customer c
    LEFT JOIN  (
                  SELECT * FROM  customer_data ORDER BY id DESC
              ) customer_data ON (customer_data.customer_id = c.customer_id)
    GROUP BY  c.customer_id          
    WHERE     CONCAT(title, ' ', forename, ' ', surname) LIKE '%Smith%' 
    LIMIT     10, 20;
    
  8. ==============================

    8.그것은 "customer_data"테이블에 실제 데이터를 로깅하는 좋은 아이디어입니다. 당신이 원하는대로이 데이터를 사용하면 "customer_data"테이블에서 모든 데이터를 선택할 수 있습니다.

    그것은 "customer_data"테이블에 실제 데이터를 로깅하는 좋은 아이디어입니다. 당신이 원하는대로이 데이터를 사용하면 "customer_data"테이블에서 모든 데이터를 선택할 수 있습니다.

  9. from https://stackoverflow.com/questions/3619030/mysql-join-the-most-recent-row-only by cc-by-sa and MIT license