Làm cách nào để db_select DISTINCT trên một trường cụ thể trong Drupal 7?


7

Tôi hiểu rằng bạn có thể chỉ định -> differ () trên câu lệnh db_select để nó chỉ trả về các giá trị riêng biệt khi xem TẤT CẢ các trường. Nhưng điều tôi muốn là trả về các giá trị khác biệt bằng cách chỉ nhìn vào MỘT trường. Đây là mã của tôi:

$event_table = db_select('my_table', 'e')
    ->distinct()
    ->orderBy('e.time', 'ASC');//ORDER BY
$event_table->join('node', 'n', 'e.nid = n.nid'); //JOIN node with events
$event_table->groupBy('e.time');//GROUP BY time
$event_table->fields('e')//SELECT the fields from events
    ->fields('n',array('type','status','title'))//SELECT the fields from node
    ->orderBy('e.time', 'ASC');//ORDER BY

$result_event_table = $event_table->execute();
$result_event_table = $result_event_table->fetchAllAssoc('time');

Giả sử tôi muốn cột riêng biệt là e.nid. Bạn sẽ nghĩ -> khác biệt ('e.nid') sẽ hoạt động nhưng nó vẫn trả về các giá trị riêng biệt dựa trên tất cả các trường (nghĩa là khác biệt (cột1, cột2, cột3, v.v.).


1
Bất kỳ cơ hội nào bạn có thể đưa ra một mẫu SQL đầu ra mà bạn đang tìm kiếm? Điều đó sẽ giúp bạn dễ dàng tìm ra cách dỗ dành db_selectđể làm điều tương tự
Clive

Câu trả lời:


12

Giả sử bạn đang cố gắng truy cập khoảng truy vấn này:

SELECT DISTINCT e.nid AS nid, e.time AS time, n.type AS type, n.status AS status, n.title AS title
FROM 
{my_table} e
INNER JOIN {node} n ON n.nid = e.nid
GROUP BY e.time
ORDER BY e.time ASC

Bạn sẽ sử dụng:

$query = db_select('my_table', 'e')
  ->distinct()
  ->fields('e', array('nid', 'time', 'foo', 'bar'))
  ->fields('n', array('type', 'status', 'title'))
  ->groupBy('e.time')
  ->orderBy('e.time');

$query->join('node', 'n', 'n.nid = e.nid');

Điều này chỉ mang đến cho tôi tất cả các lĩnh vực riêng biệt, không chỉ là khác biệt
CHRIS

Tôi không chắc ý của bạn là gì, ở trên là một truy vấn riêng biệt ... bạn đang cố gắng tạo ra SQL nào?
Clive

1
giả sử có '4' '4' '5' '5' trong cột nid với một cột tương ứng có tên là 'loại' với 'a' 'b' 'c' 'd'. tốt, nếu tôi chọn khác biệt trên cả hai cột (nid, type), kết quả sẽ có 4 hàng. nhưng nếu tôi chọn khác biệt trên JUST nid, kết quả sẽ có 2 hàng. Tôi đang cố gắng chọn khác biệt trên JUST nid
CHRIS

2
Tôi nghĩ bạn đang hiểu sai về cách nhóm hoạt động trong SQL ... để thực hiện những gì bạn mô tả, bạn cần xóa cột loại khỏi các trường đã chọn
Clive

7

DISTINCT thực sự là một công cụ sửa đổi bài toàn cầu cho CHỌN, nghĩa là trái ngược với CHỌN TẤT CẢ (trả về tất cả các câu trả lời), đó là CHỌN DISTINCT (trả về tất cả các câu trả lời duy nhất). Vì vậy, một DISTINCT duy nhất hoạt động trên TẤT CẢ các cột mà bạn cung cấp.

Điều này làm cho nó thực sự khó sử dụng DISTINCT trên một cột duy nhất, trong khi lấy các cột khác, mà không thực hiện các bước lùi cực kỳ xấu xí.

Câu trả lời đúng là sử dụng NHÓM THEO trên các cột mà bạn muốn có câu trả lời duy nhất:


Chính xác. Đó là lý do tại sao DBTNG có nó ở cấp truy vấn. Lần duy nhất DISTINCT là cấp cột (hoặc trông có vẻ mơ hồ) là khi bạn thực hiện COUNT(DISTINCT foo)nhưng ngay cả khi đó là công cụ sửa đổi của hàm tổng hợp.

2

Loại bỏ ->distinct()và thay thế nó bằng$event_table->AddExpression('distinct e.nid', 'nid');

Thích như vậy:

$event_table = db_select('my_table', 'e');
$event_table->AddExpression('distinct e.nid', 'nid')
$event_table->orderBy('e.time', 'ASC');//ORDER BY
$event_table->join('node', 'n', 'e.nid = n.nid'); //JOIN node with events
$event_table->groupBy('e.time');//GROUP BY time

// you need to outline all fields here, can't use e.*
$event_table->fields('e')//SELECT the fields from events

    ->fields('n',array('type','status','title'))//SELECT the fields from node
    ->orderBy('e.time', 'ASC');//ORDER BY

$result_event_table = $event_table->execute();
$result_event_table = $result_event_table->fetchAllAssoc('time');

PDOException: SQLSTATE [42000]: Lỗi cú pháp hoặc vi phạm truy cập: 1064 Bạn có lỗi trong cú pháp SQL của mình; kiểm tra hướng dẫn tương ứng với phiên bản máy chủ MySQL của bạn để biết đúng cú pháp để sử dụng gần 'e.nid AS nid TỪ mcc_notify_event_queue e INNER THAM GIA nút n ON e.nid' ở dòng 1: CHỌN e. *, n.type AS , n.status AS status, n.title AS title, e.nid AS anid TỪ {mcc_notify_event_queue} e INNER THAM GIA {nút} n ON e.nid = n.nid NHÓM THEO e.time ORDER BY e.time ASC; Mảng ()
CHRIS

không thể sử dụng e. * và e.nid riêng biệt, gây ra lỗi. Bạn sẽ cần phải viết ra các lĩnh vực của bạn như tôi đã lưu ý ở trên.
Scott Joudry

Tôi vẫn nhận được một lỗi. Tất cả những gì tôi đã làm là thay đổi mã của bạn thành $ event_table-> các trường ('e', mảng ('nid', 'time', 'event_type')) // CHỌN các trường từ các sự kiện
CHRIS

bạn vẫn đang chọn nid hai lần trong trường hợp đó giải thích lỗi. Hãy thử $ event_table-> các trường ('e', mảng ('thời gian', 'event_type'))
Scott Joudry

vẫn còn một lỗi khác biệt e.nid AS nid TỪ my_module_event_queue e INNER THAM GIA nút n ON e.nid 'ở dòng 1: CHỌN e.time AS time, e.event_type AS event_type, n.type AS type, n.status AS n.title AS title, e.nid AS nid TỪ {my_module_event_queue} e INNER THAM GIA {nút} n ON e.nid = n.nid NHÓM THEO e.time ORDER BY e.time ASC;
CHRIS

-1

Nếu bạn sử dụng truy vấn này thì nó cung cấp truy vấn riêng biệt phù hợp.

<?php  

$select = db_select('service_payment_transaction','o');
$select->distinct('o.transaction_id');
$select->innerJoin('users', 'u', 'u.uid = o.user_id');
$select->fields('o');
$select->fields('u');
$select->condition('o.service_gv_code','','!=');
$select->range($start,$page_count);
$select->groupBy('o.service_gv_code');
$select->orderBy('transaction_id', 'DESC');
$result_query = $select->execute();

1
Hàm riêng biệt lấy một boolean làm đối số của nó, không phải là một chuỗi.
Đêm giao thừa
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.