web-dev-qa-db-ja.com

drupalタイムスタンプでノードリビジョンを取得

ユーザーが過去にクリックしたタイムスタンプに基づいてカスタムフィールドの値を取得するモジュールを構築しています。

あまりにも具体的で複雑にしないように、他のユーザーもこれを使用できるように質問を簡略化しました。

基本的に私はpop_links_stats(タイムスタンプがあります)、node、node_revision、およびfield_revision_field_customテーブルから選択しています:

$query2 = db_select('pop_links_stats', 'p');    
$query2->join('node', 'n', 'n.nid = p.nid');
$query2->join('node_revision', 'nr', 'nr.nid = n.nid');
$query2->join('field_revision_field_custom', 'f', 'nr.vid = f.revision_id');

私はすでに$ nidを持っているので、条件をその$ nidに設定しました

$query2->condition('n.nid', $node->nid);

グループ化するので、ノードごと、IPごとに1日1回の「クリック」のみが選択されます(完全を期すために以下を追加しました。これは必要ですが、私の質問とは少し関係ないので、問題がない場合はgroupByを無視してください。 )

$query2->groupBy('DATE(FROM_UNIXTIME(p.timestamp))')->groupBy('n.nid')->groupBy('p.hostname');

必要なフィールドを選択します(現時点ではリビジョンIDのみ):

$query2->fields('nr', array('vid'));

だから私の推測はjoin the node_revision table and selecting the max vid where nr.timestamp <= p.timestamp and n.nid = nr.nid OR 'selecting' the max nr.timestamp where nr.timestamp <= p.timestamp

しかし、drupal DB APIでそれを実装するのに問題があります

編集:

MySQLで使用したクエリで、必要な結果が得られます。

SELECT p.cid, FROM_UNIXTIME(p.timestamp), FROM_UNIXTIME(nrev.timestamp), n.nid, nrev.vid FROM pop_links_stats p
JOIN node n ON n.nid = p.nid
JOIN node_revision nrev ON nrev.vid = (SELECT max(vid) FROM node_revision nr WHERE nr.nid = p.nid AND nr.timestamp <= p.timestamp )
GROUP BY DATE(FROM_UNIXTIME(p.timestamp)), p.nid, p.hostname

だから私が探しているのはどのように参加するかです:

JOIN node_revision nrev ON nrev.vid = (SELECT max(vid) FROM node_revision nr WHERE nr.nid = p.nid AND nr.timestamp <= p.timestamp )
1
FLY

このような高度な結合をAPIクエリに組み込むための構造化された方法はないようです...そのため、おそらく手動で実行する必要があります。

$query = db_select('pop_links_stats', 'p')
  ->fields('p', array('cid'))
  ->fields('n', array('nid'))
  ->fields('nrev', array('vid'))
  ->groupBy('DATE(FROM_UNIXTIME(p.timestamp))')
  ->groupBy('p.nid')
  ->groupBy('p.hostname');

$query->addExpression('FROM_UNIXTIME(p.timestamp)', 'p_timestamp');
$query->addExpression('FROM_UNIXTIME(nrev.timestamp)', 'nrev_timestamp');

$query->join('node', 'n', 'n.nid = p.nid');
$query->join('node_revision', 'nrev', 'nrev.vid = (SELECT max(vid) FROM {node_revision} nr WHERE nr.nid = p.nid AND nr.timestamp <= p.timestamp )');

それは生成します:

SELECT p.cid AS cid, n.nid AS nid, nrev.vid AS vid, FROM_UNIXTIME(p.timestamp) AS p_timestamp, FROM_UNIXTIME(nrev.timestamp) AS nrev_timestamp
FROM 
{pop_links_stats} p
INNER JOIN {node} n ON n.nid = p.nid
INNER JOIN {node_revision} nrev ON nrev.vid = (SELECT max(vid) FROM node_revision nr WHERE nr.nid = p.nid AND nr.timestamp <= p.timestamp )
GROUP BY DATE(FROM_UNIXTIME(p.timestamp)), p.nid, p.hostname
1
Clive