Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Truy vấn cho bài đăng và thẻ trong cùng một truy vấn

Sẽ tốt hơn nếu bạn không tham gia group_concat giải pháp vì nó không đáng tin cậy do độ dài ký tự, nó có giới hạn mặc định là 1024 ký tự để ghép nhưng nó có thể được tăng lên được xác định trong thủ công nhưng bạn không thể hoàn toàn dựa vào giới hạn đã xác định thay vào đó bạn có thể xử lý nó trong lớp ứng dụng của mình (php) giống như bạn đang tìm nạp dữ liệu và ở đâu đó bạn muốn hiển thị bài đăng và các thẻ liên quan của nó, bạn vẫn có thể sử dụng truy vấn tham gia của mình với thứ tự theo bài đăng ngay bây giờ mỗi bài đăng có thể có nhiều thẻ, do đó, tập hợp kết quả sẽ có dữ liệu bài đăng trùng lặp do mỗi hàng bài đăng sẽ có một thẻ và một hàng khác có cùng bài đăng sẽ có thẻ thứ hai, v.v. Bây giờ khi bạn xem qua kết quả của mình, mỗi bài đăng chỉ hiển thị một lần thêm một số séc

$this->db->select('p.*,t.*');
$this->db->from('posts p');
$this->db->join('tags_map tm', 't.id_post = p.id');
$this->db->join('tags t', 't.id = tm.id_tag');
$this->db->order_by('p.id asc,t.id asc');
$results = $this->db->get();

Trong truy vấn trên, tôi đã thêm t.* để chọn tất cả bài đăng và các thẻ liên quan của nó hiện có trong vòng lặp $currentParent sẽ có một id bài đăng trước đó trong vòng lặp kiểm tra xem bài đăng đó có giống nhau không sau đó hiển thị các thẻ của nó nếu điều kiện trả về false thì bài đăng mới hiển thị tiêu đề bài đăng bằng cách sử dụng đánh dấu (h1), tôi đã chọn tất cả các cột từ cả hai bảng nhưng bạn chỉ nên thêm vào cột từ bảng thẻ và nếu bài đăng và bảng thẻ có các cột cùng tên thì trong truy vấn đã xác định chúng bằng các bí danh khác nhau

$currentParent = false;
foreach ($results as $post) {
    if ($currentParent != $post->id) {
        echo '<h1>' . $post->title . '</h1>';
        $currentParent = $post->id;
    }
    echo '<p>' . $post->name . '</p>'; /** here list tags info*/
    echo '<p>' . $post->tag_other_details . '</p>'; 
    ...
}

Đánh dấu kết quả sẽ giống như

<h1>Post title 1</h1>
    <p>tag 1</p>
    <p>tag 2</p>
<h1>Post title 2</h1>
    <p>tag 3</p>...

Nếu bạn không hiển thị dữ liệu và bạn đang sử dụng nó ở một số nơi khác (dịch vụ web) thì vẫn sử dụng một truy vấn đã kết hợp và chuyển đổi dữ liệu của bạn bằng cách tạo mảng / đối tượng, mỗi bài đăng có một mảng các thẻ liên quan giống như bên dưới

$posts =array();
foreach ($results as $post) {
 $posts[$post->id]['title'] = $post->title;
 $posts[$post->id]['tags'][] =array('id' => $tag->id ,'name' =>$post->name);
}

có một cách khác rất không được khuyến khích nhận bài đăng và trong vòng lặp lấy thẻ bằng cách chạy truy vấn bây giờ giải pháp này sẽ hoạt động nhưng sẽ liên quan đến các truy vấn không mong muốn, do đó sẽ có thêm một truy vấn được thực thi cho mỗi bài đăng.

Bây giờ nếu bạn thực sự muốn gắn bó với group_concat cách tiếp cận để trả lời câu hỏi của bạn I'm not sure if I can trust the order? cũng có một cách bạn có thể thêm order by trong group_concat để các thẻ được nối kết quả sẽ được sắp xếp theo thứ tự và đối với cột thứ hai, bạn có thể đặt các tiêu chí sắp xếp tương tự

$this->db->select('p.*,group_concat(t.name order by t.id) as thetags,
                       group_concat(t.relevance order by t.id) as therelevances');
$this->db->from('posts p');
$this->db->join('tags_map tm', 't.id_post = p.id');
$this->db->join('tags t', 't.id = tm.id_tag');
$this->db->group_by('p.id');


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. AWS MySQL RDS so với AWS DynamoDB

  2. Chèn dấu thời gian vào cơ sở dữ liệu + 7 ngày

  3. sử dụng tìm kiếm toàn văn để tìm kiếm các từ chưa hoàn chỉnh trong mysql

  4. MySQL có hỗ trợ ràng buộc kiểm tra không?

  5. Quá nhiều kết nối sử dụng Hibernate và mysql