在SQL中设置差异

时间:2016-06-29 18:25:58

标签: mysql sql

我有以下查询,它为我提供了一个group_concat商店标题可用:

http://sqlfiddle.com/#!9/e52b53/1/0

我目前使用的查询给了我这个:

select 
    title.id, title.name, group_concat(distinct store order by store)
from
    version inner join title on version.title_id=title.id inner join version_price 
    on version_price.version_id=version.id 
group by 
    title_id

id  name    group_concat(distinct store order by store) 
1   Titanic Google,iTunes                               
2   Avatar  iTunes  

我想添加一个额外的列,它给出了以下(硬编码)商店之间的设置差异:("iTunes", "Google", "Amazon")。然后正确的查询会给我:

id  name         group_concat(distinct store order by store)    not_on
1   Titanic      Google,iTunes                                  Amazon
2   Avatar       iTunes                                         Amazon,Google

我该怎么做?

3 个答案:

答案 0 :(得分:1)

您可以加入所有商店的表格。我将在子查询中列出它们,但实际上创建这样一个表会更好:

select     title.id, 
           title.name, 
           group_concat(distinct store order by store),
           group_concat(distinct nullif(stores.name, store) order by stores.name)
from       version
inner join title 
        on version.title_id=title.id 
cross join (select 'iTunes' as name union
            select 'Google' union
            select 'Amazon') as stores
left join  version_price 
        on version_price.version_id=version.id
       and version_price.store = stores.name
group by   title.id

SQL fiddle

请注意,现在加入version_price与外部联接非常重要:

这是因为inner join会消除 stores 子查询中的不匹配值。如果left join没有发生:相反, version_price 的字段表示为null,对于某个 stores.name 则没有在 version_price 中匹配。

因此,在分组发生之前,您实际上有更多记录,但这些额外的null值对第一个group_concat没有贡献。然而,他们,只有那些,对第二个做出了贡献。

改进数据库模型

将商店列在参考表中,按名称编制索引会更好。或者甚至更好,为这些商店提供id,并重新设计version_price表以使用store_id作为外键,而不是store(名称)。

答案 1 :(得分:1)

子查询怎么样?

{{1}}

这里的小提琴版:http://sqlfiddle.com/#!9/af9e98/7

答案 2 :(得分:1)

http://sqlfiddle.com/#!9/e52b53/45

由于商店名称是硬编码的,为什么不这样做?至少它没有在查询执行计划中添加额外的连接。

select 
  title.id, 
  title.name, 
  group_concat(distinct store order by store) as ins,
  concat_ws(
    ',',
    if(group_concat(distinct store order by store) like '%Amazon%', NULL, 'Amazon'),
    if(group_concat(distinct store order by store) like '%Google%', NULL, 'Google'),
    if(group_concat(distinct store order by store) like '%iTunes%', NULL, 'iTunes')
  ) as not_on
from version 
inner join title on version.title_id=title.id 
inner join version_price on version_price.version_id=version.id 
group by title_id