SQL连接表,如果没有链接,则为空值

时间:2019-07-15 09:34:18

标签: sql

我在下面也看到了类似的问题,但是解决起来有些困难。

我有2个表-1个表:“ user_watch_list”,其中包含“ movie_id” 第二个表:“ streaming”,其中包含“ movie_id”。

结构和示例数据:

表:user_watch_list

user_id, movie_id  
1 | 1  
1 | 2  
1 | 3  
1 | 4

表格:流式传输

movie_id, channel
1 | SKY
1 | NOW TV
2 | SKY
3 | SKY

我希望输出显示唯一的电影ID,以及显示在流表中的时间计数。

这两个ID

我希望输出显示唯一的电影ID,以及显示在流表中的时间计数。

这是我尝试过的过程。

这将显示用户观看列表中的所有电影。

$select = 'SELECT *';
$from = ' FROM user_watch_lists ';
$where = ' WHERE user_id ='.$loggedUser. ' ORDER BY updated_at DESC ';

这仅显示该用户在流式传输表上的内容。

$select = 'SELECT DISTINCT user_watch_lists.movie_id FROM user_watch_lists';
$from = '  INNER JOIN streaming ON streaming.movie_id= user_watch_lists.movie_id ';
$where = ' WHERE user_watch_lists.user_id ='.$loggedUser. '  ORDER BY updated_at DESC ';

我希望输出显示唯一的电影ID,以及显示在流表中的时间计数。

user_id = 1的示例

movie_id, count 
1         2 
2         1 
3         1 
4         0

4 个答案:

答案 0 :(得分:2)

select a.movie_id, count(*) from streaming a
left join user_watch_list b on a.movie_id = b.movie_id
where user_id = '1'
group by a.movie_id 

您需要user.id的联接,并且'group by'使'count','sum','avg'等所有函数都适用于您想要的字段。

答案 1 :(得分:1)

更新

将计数功能应用于movie_id的列streaming可以使用简单的左联接。这是可行的,因为count跳过了空值。计算整个记录(count(*))会产生错误的结果。有关说明,请参见this fiddle

因此,建议采用戈登·林诺夫(GordonLinoff)的答案(应该是公认的答案)


原始

使用左联接将streaming记录与users表中的电影项目相关联,并添加一个合成标志进行计数。

      select base.movie_id
           , sum(to_count)   items
        from (
                      select u.movie_id
                           , case when s.movie_id is null then 0 else 1 end to_count 
                        from users     u
                   left join streaming s
                          on s.movie_id = u.movie_id
                       where u.user_id = 1
             ) base
    group by base.movie_id
    order by movie_id
           ;

(请注意,在您的设置中需要替换user_id。出于安全原因,最好使用主机变量和 not 进行字符串操作)。

使用这种方法,您需要为左联接的计数标志(或具有相同用途的类似设备)为最前面的表的每个记录至少产生1条记录。如果碰巧第二个表中没有满足连接条件的记录,则源于hat表的字段在结果集中为空。
   因此,在进行分组和计数时,您必须区分在联接表中找不到匹配项或恰好有1个匹配项的情况。
   上面的解决方案通过添加标记不匹配的{users)记录的合成数字属性并将结果集汇总到该属性上来实现。

db-fiddle上看到它(它在postgresql中[您没有指定正在使用的dbms],但是是标准sql)

替代

使用内部联接对streaming中有记录的电影进行实际计数,并为streaming中不存在的所有电影的合成记录补充结果集。

      select u.movie_id
           , count(*)   items
        from users     u
        join streaming s
          on s.movie_id = u.movie_id
       where u.user_id = 1
    group by u.movie_id
   union all 
      select u.movie_id
           , 0          items
        from users     u
       where u.user_id = 1
         and not exists (
                 select 1
                   from streaming s
                  where s.movie_id = u.movie_id 
             )
    order by movie_id
           ;

(再次修改用户的条件)

提琴是here

答案 2 :(得分:1)

SELECT user_watch_list。*,count(streaming.movi​​e_id)AS计数 来自user_watch_list 左加入流 开启user_watch_list.movi​​e_id = streaming.movi​​e_id

答案 3 :(得分:1)

这是一个简单的left join和聚合:

select uwl.movie_id, count(s.movie_id)
from user_watch_list uwl left join
     streaming s 
     on s.movie_id = uwl.movie_id and
where uwl.user_id = 1
group by uwl.movie_id