【问题标题】:Query help; do I need a subquery?查询帮助;我需要子查询吗?
【发布时间】:2011-05-20 16:33:20
【问题描述】:

(已经在 drupal.stackexchange.com 上发布,但没有任何回应;因为问题是 mysql 特定的,希望这里有人可以提供帮助...)

我继承了在我们的主页上运行的这段代码。它用于自定义显示特定的相关信息。设置方法如下:

我们有一篇文章。它有一系列节点引用字段,允许我们链接相关图像(实际上是节点本身,其中包含头像和一些文本;它不是实际附加的图像。)每个头像都有一个通过 ImageCache 创建的缩略图,以便我们可以在搜索结果和列表类型的页面上显示一个小版本。

我们有一个新要求,如果特定文章的相关图像节点具有与其关联的特定分类术语 (tid),则它的显示方式应与其他图像不同。

现有的查询(不是我写的)如下所示:

SELECT DISTINCT n.title, nr.teaser, n.nid, DATE_FORMAT(FROM_UNIXTIME(n.created), '%M %e, %Y') AS date, f.filepath AS image, cfri.field_related_images_nid as image_id 

FROM node n JOIN node_revisions nr ON n.nid = nr.nid 
LEFT JOIN content_field_related_images cfri ON (n.nid = cfri.nid AND cfri.delta = 0) 
LEFT JOIN content_field_att_file cfaf ON cfri.field_related_images_nid = cfaf.nid 
LEFT JOIN files f ON cfaf.field_att_file_fid = f.fid  
JOIN term_node tn2 ON n.nid = tn2.nid 

WHERE n.status = 1 
AND n.type = 'article'   
AND nr.body LIKE '%kimberly-clark%' 
AND tn2.tid = 143 
ORDER BY n.created DESC LIMIT 3

这会返回一个如下所示的记录集:

TITLE         |  TEASER           |  NID |  DATE            |  IMAGE                            | IMAGE_ID
==========================================================================================================
Exec Profile  |  Could you please | 67491 | April 29, 2011  | sites/default/files/kcjones.jpg   | 67572
Unilver Ads   |  Unilever topped  | 67421 | April 20, 2011  | sites/default/files/unilever.jpg  | 66889

这一切都很好。但是我需要做的是(在同一个查询中,不知何故)还返回与 term_node 表中的 image_id 一起的 tid。对于单个图像节点本身来说,查询很简单:

SELECT tid FROM term_node WHERE nid = 67572

但是如何修改现有查询以根据查询主要部分中找到的 image_id 引入 tid?我猜我需要某种子查询,但这超出了我的 sql 代码的限制......

------------------------------------------ ----------------------------------------------

UPDATE 每个请求,这里是查询中使用的所有表的表结构:

-- Table structure for table `content_field_att_file`
--

CREATE TABLE IF NOT EXISTS `content_field_att_file` (
  `vid` int(10) unsigned NOT NULL DEFAULT '0',
  `nid` int(10) unsigned NOT NULL DEFAULT '0',
  `delta` int(10) unsigned NOT NULL DEFAULT '0',
  `field_att_file_fid` int(11) DEFAULT NULL,
  `field_att_file_list` tinyint(4) DEFAULT NULL,
  `field_att_file_data` text,
  PRIMARY KEY (`vid`,`delta`),
  KEY `nid` (`nid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Table structure for table `content_field_related_images`
--

CREATE TABLE IF NOT EXISTS `content_field_related_images` (
  `vid` int(10) unsigned NOT NULL DEFAULT '0',
  `nid` int(10) unsigned NOT NULL DEFAULT '0',
  `delta` int(10) unsigned NOT NULL DEFAULT '0',
  `field_related_images_nid` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`vid`,`delta`),
  KEY `nid` (`nid`),
  KEY `field_related_images_nid` (`field_related_images_nid`),
  KEY `delta` (`delta`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Table structure for table `files`
--

CREATE TABLE IF NOT EXISTS `files` (
  `fid` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `uid` int(10) unsigned NOT NULL DEFAULT '0',
  `filename` varchar(255) NOT NULL DEFAULT '',
  `filepath` varchar(255) NOT NULL DEFAULT '',
  `filemime` varchar(255) NOT NULL DEFAULT '',
  `filesize` int(10) unsigned NOT NULL DEFAULT '0',
  `status` int(11) NOT NULL DEFAULT '0',
  `timestamp` int(10) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`fid`),
  KEY `uid` (`uid`),
  KEY `status` (`status`),
  KEY `timestamp` (`timestamp`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=100810 ;

-- --------------------------------------------------------

--
-- Table structure for table `node`
--

CREATE TABLE IF NOT EXISTS `node` (
  `nid` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `vid` int(10) unsigned NOT NULL DEFAULT '0',
  `type` varchar(32) NOT NULL DEFAULT '',
  `language` varchar(12) NOT NULL DEFAULT '',
  `title` varchar(255) NOT NULL DEFAULT '',
  `uid` int(11) NOT NULL DEFAULT '0',
  `status` int(11) NOT NULL DEFAULT '1',
  `created` int(11) NOT NULL DEFAULT '0',
  `changed` int(11) NOT NULL DEFAULT '0',
  `comment` int(11) NOT NULL DEFAULT '0',
  `promote` int(11) NOT NULL DEFAULT '0',
  `moderate` int(11) NOT NULL DEFAULT '0',
  `sticky` int(11) NOT NULL DEFAULT '0',
  `tnid` int(10) unsigned NOT NULL DEFAULT '0',
  `translate` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`nid`),
  UNIQUE KEY `vid` (`vid`),
  KEY `node_changed` (`changed`),
  KEY `node_created` (`created`),
  KEY `node_moderate` (`moderate`),
  KEY `node_promote_status` (`promote`,`status`),
  KEY `node_status_type` (`status`,`type`,`nid`),
  KEY `node_title_type` (`title`,`type`(4)),
  KEY `node_type` (`type`(4)),
  KEY `uid` (`uid`),
  KEY `tnid` (`tnid`),
  KEY `translate` (`translate`),
  KEY `status` (`status`,`type`,`created`),
  KEY `status_2` (`status`,`type`,`created`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=102682 ;

-- --------------------------------------------------------

--
-- Table structure for table `node_revisions`
--

CREATE TABLE IF NOT EXISTS `node_revisions` (
  `nid` int(10) unsigned NOT NULL DEFAULT '0',
  `vid` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `uid` int(11) NOT NULL DEFAULT '0',
  `title` varchar(255) NOT NULL DEFAULT '',
  `body` longtext NOT NULL,
  `teaser` longtext NOT NULL,
  `log` longtext NOT NULL,
  `timestamp` int(11) NOT NULL DEFAULT '0',
  `format` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`vid`),
  KEY `nid` (`nid`),
  KEY `uid` (`uid`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=102690 ;

-- --------------------------------------------------------

--
-- Table structure for table `term_node`
--

CREATE TABLE IF NOT EXISTS `term_node` (
  `nid` int(10) unsigned NOT NULL DEFAULT '0',
  `vid` int(10) unsigned NOT NULL DEFAULT '0',
  `tid` int(10) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`tid`,`vid`),
  KEY `vid` (`vid`),
  KEY `nid` (`nid`),
  KEY `tid` (`tid`,`nid`),
  KEY `tid_2` (`tid`,`nid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

【问题讨论】:

  • 我不明白这个问题。您已经加入 term_node。为什么不能只将 tid 添加到 select 子句中?还是您的意思是您需要查找与您已经加入的不同的 term_node 记录?如果是这样,该记录的选择标准是什么?在您的示例中,您只需说 nid=。这是已经在选择中的同一个nid吗?如果不是,那是什么?
  • 因为连接返回 n.nid 的 tid。我需要 cfri.field_related_images_nid 的 tid,它是初始选择语句的一部分。

标签: mysql drupal-6


【解决方案1】:

您可以为term_node 表添加第二个连接并将列添加到选择列表:

SELECT DISTINCT n.title, nr.teaser, n.nid, DATE_FORMAT(FROM_UNIXTIME(n.created), '%M %e, %Y') AS date, f.filepath AS image, cfri.field_related_images_nid as image_id, tn_img.tid as image_tid

FROM node n JOIN node_revisions nr ON n.nid = nr.nid 
LEFT JOIN content_field_related_images cfri ON (n.nid = cfri.nid AND cfri.delta = 0) 
LEFT JOIN content_field_att_file cfaf ON cfri.field_related_images_nid = cfaf.nid 
LEFT JOIN files f ON cfaf.field_att_file_fid = f.fid  
JOIN term_node tn2 ON n.nid = tn2.nid
LEFT JOIN term_node tn_img ON cfri.field_related_images_nid = tn_img.nid

WHERE n.status = 1 
AND n.type = 'article'   
AND nr.body LIKE '%kimberly-clark%' 
AND tn2.tid = 143 
ORDER BY n.created DESC LIMIT 3

这是重要的一行:LEFT JOIN term_node tn_img on cfri.field_related_images_nid = tn_img.nid,不要忘记将该列也添加到选择列表中!

可能是我的查询错了,我们没有太多关于表结构的信息,如果不行,贴出数据库架构:)

更新以反映 cmets 中的讨论

【讨论】:

  • 我先试试你的查询;这是一个drupal安装,所以数据库很大。如果这不起作用,我会尝试输出相关表的架构。
  • 不,返回了 3000 多条记录,而应该只有 3 条记录。我会尝试发布表格信息。
  • @EmmyS 尝试在添加的行中将JOIN 替换为INNER JOIN。
  • 哦,这么接近了...但是我们需要返回没有相关图像的节点记录(或者有图像但图像没有税。术语。)内连接完全消除了任何没有图像的记录。
  • @EmmyS 使用 LEFT JOIN 然后 :)
【解决方案2】:

我可能遗漏了一些东西,但这应该可以工作

SELECT DISTINCT n.title, nr.teaser, n.nid, **tn2.tid** DATE_FORMAT(FROM_UNIXTIME(n.created), '%M %e, %Y') AS date, f.filepath AS image, cfri.field_related_images_nid as image_id 

FROM node n JOIN node_revisions nr ON n.nid = nr.nid 
JOIN term_node tn tn2 ON n.nid = tn2.nid
LEFT JOIN content_field_related_images cfri ON (n.nid = cfri.nid AND cfri.delta = 0) 
LEFT JOIN content_field_att_file cfaf ON cfri.field_related_images_nid = cfaf.nid 
LEFT JOIN files f ON cfaf.field_att_file_fid = f.fid  

WHERE n.status = 1 
AND n.type = 'article'   
AND nr.body LIKE '%kimberly-clark%' 
AND tn2.tid = 143 
ORDER BY n.created DESC LIMIT 3

【讨论】:

  • 见 cmets 到初始帖子; tn2.tid 包含在 where 子句中以将结果限制为 n。 tid 为 143 的记录。我希望包含来自 cfri 的结果,对 tid 没有限制,只要 nid 与记录集中返回的 cfri.related_images_nid 匹配。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-03
相关资源
最近更新 更多