sai*_*ran 12 php mysql database join codeigniter
我有四张桌子如下
人数:
------------------------------------------------------------------------------------------------
| list_id |user_id | name | category | fees | details |created_on |
------------------------------------------------------------------------------------------------
| 90cc57a4-f782-4c57-ac98-1965c57ece57 |user 100 |satwik| music | 500 | dummy |2015-08-02 |
------------------------------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
将我的list_id从随机字符串更改为UUID.
从这个关于php.net的评论
看到这个stackoverflow问题
在列表表中list_id是主键,我知道使用autoincreament是最好的,但我的要求是这样的.和s.no是其余表的主键.
我需要从PHP端生成一个随机密钥,因为要在会话中设置list_id并避免在会话中设置list_id的另一个查询. 喜欢:
----------------------------------------------------------------
|.sno | list_id | user_id | likes |
----------------------------------------------------------------
| 1 | 90cc57a4-f782-4c57-ac98-1965c57ece57 | user110 | 1 |
----------------------------------------------------------------
| 2 | 90cc57a4-f782-4c57-ac98-1965c57ece57 | user215 | 1 |
----------------------------------------------------------------
| 3 | 90cc57a4-f782-4c57-ac98-1965c57ece57 | user200 | 1 |
----------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
评论:
-------------------------------------------------------------------------
|.sno | user_id | list_id | comment |
-------------------------------------------------------------------------
| 1 | user 205| 90cc57a4-f782-4c57-ac98-1965c57ece57 | dummy comment |
-------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
浏览次数:
----------------------------------------------------------------
|.sno | list_id | user_id | views |
----------------------------------------------------------------
| 1 | 90cc57a4-f782-4c57-ac98-1965c57ece57 | user110 | 2 |
----------------------------------------------------------------
| 2 | 90cc57a4-f782-4c57-ac98-1965c57ece57 | user215 | 1 |
----------------------------------------------------------------
| 3 | 90cc57a4-f782-4c57-ac98-1965c57ece57 | user200 | 1 |
----------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
我想从列表表中获取用户ID user100的列表
并且需要从我拥有的各种表中获取视图的数量,例如,对用户列表ID的注释.
我尝试使用codeigniter中的这个查询
$this->db->select ( 'list.*,count(v.views) as views,count(l.likes) as likes,count(c.comment) as comments' )
->from ( 'listings as list' )
->join ( 'views v', 'v.list_id = list.list_id')
->join ( 'likes l', 'l.list_id = list.list_id')
->join ( 'comments c', 'c.list_id = list.list_id');
$this->db->where ( 'list.user_id', $user_id);
$query = $this->db->get ();
Run Code Online (Sandbox Code Playgroud)
我得到错误的观点,喜欢和评论计数.
这个数据库设计是好还是我需要改变任何东西.我使用连接的意愿不大,请帮助我.
编辑:
我从下面的答案中尝试了这个查询
$this->db->select ( 'l.*,count(distinct v.s_no) as views,count(distinct li.s_no) as likes,count(distinct c.s_no) as comments' ,false)
->from ( 'listings as l' )
->join ( 'likes li', 'l.list_id = li.list_id')
->join ( 'comments c', 'l.list_id = c.list_id')
->join ( 'views v', 'l.list_id = v.list_id')
->where ( 'l.user_id', $id);
Run Code Online (Sandbox Code Playgroud)
我得到了我想要的东西,但如果我没有任何评论或观点或喜欢,这种查询方式失败(返回null).
考虑到你的结构,你的每个表应该有一个字段定义为a primary key
,列表表(喜欢,视图和注释)的关联应该与该键相关,因为foreign key
我希望sno
字段被定义为每个表的主键,所以在你的list_id
喜欢视图和注释中的case 列将引用列表表,其中自动生成的列表ID为1,2,3,因此list_id
不再需要列表中的列,同样的情况将适用于您的用户表和它自动生成的用户id现在是你正在使用多个连接的查询部分,这样就会有@FuzzyTree提到的交叉产品并且在结果集上进行聚合会给你错误的结果,因此你需要一个独特的计数,这就是为什么我已经为表定义了主键,所以不需要v.views
计算v.sno
相同的数量
select l.*,
count(distinct v.sno) as views,
count(distinct li.sno) as likes,
count(distinct c.sno) as comments
from listings l
join likes li on(l.sno = li.list_id)
join comments c on(l.sno = c.list_id)
join `views` v on(l.sno = v.list_id)
where l.user_id = 'user100'
group by l.sno
Run Code Online (Sandbox Code Playgroud)
使用活动记录,您可以编写类似的查询
$this->db->select ( 'l.*,
count(distinct v.sno) as views,
count(distinct li.sno) as likes,
count(distinct c.sno) as comments' ,false)
->from ( 'listings as l' )
->join ( 'likes li', 'l.sno = li.list_id')
->join ( 'comments c', 'l.sno = c.list_id')
->join ( 'views v', 'l.sno = v.list_id')
->where ( 'l.user_id', $user_id)
->group_by( 'l.sno');
Run Code Online (Sandbox Code Playgroud)
根据您提供的数据集列表1有3个喜好,3个视图和1个评论你可以找到上面查询的附加演示,你也可以找到带有外键和级联的更新表定义(将有助于维护关系)
Fiddle Demo
编辑0喜欢/观看和评论的帖子
使用0喜欢/视图的内部联接帖子和评论将不会被返回为此您需要左连接您可以看到更新的演示并使用活动记录您可以构建如下的查询,在join()
函数中定义连接类型(左/内/右)第三个参数
$this->db->select ( 'l.*,
count(distinct v.sno) as views,
count(distinct li.sno) as likes,
count(distinct c.sno) as comments' ,false)
->from ( 'listings as l' )
->join ( 'likes li', 'l.sno = li.list_id','left')
->join ( 'comments c', 'l.sno = c.list_id','left')
->join ( 'views v', 'l.sno = v.list_id','left')
->where ( 'l.user_id', $user_id)
->group_by( 'l.sno');
Run Code Online (Sandbox Code Playgroud)
Updated Demo
如果user_id
不是唯一的likes
,comments
或者views
在进行多个连接时最终会得到叉积,这会增加您的计数。因为您\xe2\x80\x99 仅查询一个 user_id,所以子查询可能是最好的方法。
请记住将第二个参数设置为select
to false
,以便 codeigniter 不会尝试转义子查询。
$this->db->select ( 'list.*, \n (select count(*) from views v where v.user_id = list.user_id) as views,\n (select count(*) from likes l where l.user_id = list.user_id) as likes,\n (select count(*) from comments c where c.user_id = list.user_id) as comments',false)->from ( 'listings as list' );\n$this->db->where ( 'list.user_id', $user_id);\n$query = $this->db->get ();\n
Run Code Online (Sandbox Code Playgroud)\n