左连接 3 个表并在空单元格上显示真假
Posted
技术标签:
【中文标题】左连接 3 个表并在空单元格上显示真假【英文标题】:Left Join 3 Tables and Show True or False on Empty Cells 【发布时间】:2010-03-18 02:02:15 【问题描述】:好的,这可能会令人困惑,所以我希望我能正确解释。
我有 4 张桌子:
业务 相片 视频 类别
我想在主页(或其他地方)显示“精选”企业,并且我想根据是否有该企业的照片或视频在表格行中显示“是”或“否”。
示例:Joes Crab Shack 没有视频或照片,但有特色。因此,当他的行被回显时,它将显示企业名称和企业所有者,但照片或视频单元格中将没有数据,因此在视频和照片列中它会说“否”。否则,如果相反,它会说是。
Here's my pastebin
【问题讨论】:
我在想也许拥有单独的功能可能会更好,因为无论如何我都会在各个业务页面上列出照片和视频。也许我让这变得更难然后它需要?由于无论如何我都需要查询视频、照片和特价商品的功能,是否可以在显示初始表时检查数据库中是否存在这些项目?换句话说,当 Joes 的行被回显时,会运行一个函数来检查照片等?但是它怎么知道要检查 Joes 而不是 Bobs? 【参考方案1】:你可以用这样的方式作弊:
SELECT b.[other stuff],
(SELECT COUNT(1) FROM photos WHERE busid = b.id) AS photo_count,
(SELECT COUNT(1) FROM videos WHERE busid = b.id) AS video_count
FROM business AS b [etc]
photo_count
& video_count
将返回 0 或大于 0 - 在 php 中很容易得到 no/yes。这也将阻止您因每个企业拥有超过 1 张照片/视频而获得的重复结果。
警告!:将其转换为您正在使用的 ORM...我不确定 ORM 是否可以接受。但是,如果它没有对from()
和join()
中的“AS”别名大喊大叫,也许您可以在select()
中潜入子查询而不会出现任何问题。
【讨论】:
拥有一个单独的函数来根据 b.id 检查照片或视频是否更有意义? 您的意思是在 PHP 函数中?这可能更干净,但我怀疑它会产生积极的影响 - 一个查询比同样分成 3 个查询更快,如果只是因为它调用了一次数据库。 好的,只是想知道。我在使用 activerecord 进行选择计数时遇到问题。我想知道是不是我做的太多了。【参考方案2】:我要试一试。
我要做的是,在生成用于显示“特色”业务的表格时,我会调用您的数据库,通常是在生成照片和视频类别并检查输出时进行的。如果那里有东西,那么它就说是,如果从数据库返回为空,那么可以安全地假设没有任何照片或视频,因此您可以打印出一个否。
【讨论】:
您的建议有效,我在下面发布了问题的答案,但既然这是您的建议,我会给予您信任。【参考方案3】:我假设这些表是这样设置的:
-
业务信息
照片
视频
?
您将为每个企业创建一个唯一 ID(自动增量效果很好),并且每当为该企业上传照片或视频时,该记录将插入到相应的表中,并附有该 ID(ID 列或其他) .
每个表都允许企业有多个条目(如 Dyllon 所说,“一对多”)。
因此,每当您展示特色商家时,您都会使用唯一 ID 对视频和照片表运行查询并查找返回的行。行 = 是,!rows = 否。
一个问题: 您是将图像存储在数据库或文件名中并将它们上传到目录吗?
我要添加到上述建议中的唯一其他输入是构建您的表,以便表本身中永远不会有任何空值,这可能是这种情况,因为您已经有四个表用于该项目。
我第二个多维数组/对象方法对返回的数据进行存储和排序。
一个不错的方法是使用 PHP 图像函数来调整作为照片缩略图返回的第一张图像的大小 - 您也可以为每个视频捕捉一个帧 - 所以我们看起来不是是或否,而是缩略图对于两者或“无图像/视频”的 slug。
不多,但我的 $.02。
【讨论】:
【参考方案4】:SELECT b.busname
, b.busowner
, b.webaddress
, IF (EXISTS (SELECT 1 FROM photos p WHERE p.busid = b.id), 'Yes', 'No') has_photo
, IF (EXISTS (SELECT 1 FROM video v WHERE v.busid = b.id), 'Yes', 'No') has_video
FROM business b
WHERE b.featured = 1
【讨论】:
【参考方案5】:我在此假设您的照片和视频表中每个商家包含超过 1 条记录,即“一对多”关系。
在这种情况下,您将需要重新考虑您的方法,或者至少对您的数据库结果进行一些格式化。目前,如果乔斯螃蟹小屋有超过 1 个视频和/或照片,您将获得多个乔斯螃蟹小屋的结果。
如果您需要照片/视频结果,您可以在现在接收结果时对结果进行格式化,以创建一个多维数组/对象,其中 $featured['videos']
或 $featured['photos]
将包含您的连接结果,如果您的格式化数组没有'不包含 'videos' 键则没有视频结果。
如果您只需要知道它返回的行数是否超过 0 行,那么请在您的模型中创建两个新方法来计算属于特定业务的视频和照片。如果方法返回多于 0 行,则只需回显“是”,否则返回“否”。
编辑:模型函数应该是这样的
function frontPageList()
$this->db->select('b.busname, b.busowner, b.webaddress');
$this->db->select('(SELECT COUNT(1) FROM photos WHERE busid = b.id) AS photo_count', FALSE);
$this->db->select('(SELECT COUNT(1) FROM videos WHERE busid = b.id) AS video_count', FALSE);
$this->db->from ('business AS b');
$this->db->where('featured', '1');
return $this->db->get();
【讨论】:
最终我想做的是有一个单独的商业页面,所有的照片和视频都会被列出来。但是,在商业页面列表上,我只想显示他们是否有照片、视频或特价/优惠券等内容。我最好有单独的功能,一个用于显示业务信息,然后单独的功能检查照片、视频和特价商品,在列表中显示是或否,并在业务页面上显示实际结果? 您现在的查询可以很好地显示业务信息,您只需将结果格式化为多维数组,然后再将其输出到您的视图。您可能会在项目的某个时间点在模型中需要一个计数函数,您可以现在创建并使用它们或使用 tadamson 建议的嵌套查询。我将通过一个示例来编辑我的答案,说明如何将嵌套查询与 CI 的 Active Record 一起使用【参考方案6】:好的,根据你们的建议,这是我能够解决问题的方法:
型号:
function frontPageList()
$this->db->select('b.busname, b.busowner, b.webaddress, p.photoname, v.title');
$this->db->from ('business AS b');
$this->db->where('featured', '1');
$this->db->join('photos AS p', 'p.busid = b.id', 'left');
$this->db->join('video AS v', 'v.busid = b.id', 'left');
return $this->db->get();
控制:
function index()
$this->load->model('Business_model');
$data['featured'] = $this->Business_model->frontPageList();
$data['user_id'] = $this->tank_auth->get_user_id();
$data['username'] = $this->tank_auth->get_username();
$data['page_title'] = 'Welcome To Jerome - Largest Ghost Town in America';
$data['page'] = 'welcome_message'; // pass the actual view to use as a parameter
$this->load->view('container',$data);
查看:
<table id="businessTable">
<thead><tr><th>Business Name</th><th>Business Owner</th><th>Web</th><th>Photos</th><th>Videos</th></tr></thead>
<?php foreach ($featured->result() as $row): ?>
<tr>
<td><?=$row->busname?></td>
<td><?=$row->busowner?></td>
<td><a href="<?=$row->webaddress?>">Visit Site</a></td>
<td>
<?php if(isset($row->photoname)):?>
no
<?php else:?>
yes
<?php endif?>
</td>
<td>
<?php if(isset($row->title)):?>
no
<?php else:?>
yes
<?php endif?>
</td>
</tr>
<?php endforeach; ?>
</table>
【讨论】:
以上是关于左连接 3 个表并在空单元格上显示真假的主要内容,如果未能解决你的问题,请参考以下文章
处理 UICollectionView 单元格上的滑动:在 UICollectionView 或每个单元格上实现处理程序?