在 ColdFusion 中使用 SQL Join 时遇到问题



我试图在CF/SQL中做一些非常简单的事情,但似乎无法弄清楚我做错了什么。

我有这些表:

movies       genres     actors      moviesGenres     moviesActors
------       ------     ------      ------------     ------------
movieId      genreId    actorId     id               id
title        name       fname       movie            movie
                        lname       genre            actor

我正在尝试编写一个查询,该查询仅列出所有电影,以及每部电影的类型(可以进行多项选择)和每部电影的演员(再次,可以进行多项选择)。

当我编写查询以仅包含流派时,一切正常。我用于查询本身,按 movieId 分组,然后围绕流派进行单独分组。

但是当我试图包括演员时,一切都爆炸了,似乎分组崩溃了。

下面是两个联接的 SQL 查询:

SELECT m.movieId, m.title, m.releaseDate, m.description, g.name, a.fname, a.lname
FROM movies m
   INNER JOIN genres g ON g.genreId IN (SELECT genre FROM moviesGenres WHERE movie = m.movieId)
   INNER JOIN actors a ON a.actorID IN (SELECT actor FROM moviesActors WHERE movie = m.movieId)
ORDER BY m.title

提前感谢任何帮助!

更新:

Leigh 和 Mark 提供的查询似乎总体上有效,但我仍然看到演员在 .这是我的代码:

<tbody>
   <cfoutput query="variables.movieList" group="movieId">
      <tr>
         <td><a href="##">#title#</a></td>
         <td><cfoutput group="name">#name# | </cfoutput></td>
         <td><cfoutput group="actorId">#actorId# | </cfoutput></td>
      </tr>
   </cfoutput>
</tbody>

我也尝试过没有对最终标签进行分组,但这不起作用。请注意,为了测试的简单性,我将 a.lName 和 a.fName 更改为 a.actorId。

示例行如下所示:

The Godfather    Action | Drama |    1 | 2 | 1 | 2 |

您必须关联连接中的所有表。否则,你最终会得到一个笛卡尔乘积。因此,也加入联结表,而不是在子查询中使用它们。使用正确的 ORDER BY,您应该能够使用<cfoutput group="..">根据需要格式化输出。

没有经过测试,但类似的东西。

SELECT m.movieId, m.title, m.releaseDate, m.description, g.name, a.actorID, a.fname, a.lname
FROM movies m
        LEFT JOIN moviesGenres mg ON mg.movie = m.movieID
        LEFT JOIN genres g ON g.genreID = mg.genre
        LEFT JOIN moviesActors ma ON ma.movie = m.movieID
        LEFT JOIN actors a ON a.actorId = ma.actor
// since movie names may not be unique, do a secondary sort on movieID
ORDER BY m.title, m.movieID, g.Name, a.fName, a.lName

根据评论进行编辑:

正如史蒂夫所提到的,使用cfoutput group时,必须以相同的方式对结果进行排序和分组,以使功能正常工作。有关更详细的解释,请参阅他的回答。

另一种方法是使用结构来生成独特的类型和演员。请注意,上面的 sql 查询略有修改,以匹配更新后的示例。

<table border="1">
<!--- group by ID in case multiple movies have the same name --->
<cfoutput query="yourQuery" group="movieID">
    <!--- use structures to save unique genres and actors --->
    <cfset genres = {}>
    <cfset actors = {}>
    <cfoutput>
        <cfset genres[name] = true>
        <cfset actors[actorID] = true>
    </cfoutput>
    <!--- display results --->
    <tr><td>#Title#</td>
        <td>#structKeyList(genres, "|")#</td>
        <td>#structKeyList(actors, "|") #</td>
    </tr>
</cfoutput>
</table>

不确定我是否喜欢你的语法。我猜你的子选择和混叠正在搞砸你的结果。你追求的是加入这些桥表,如果我抓住你在做什么。我会做这样的事情:

SELECT m.movieId, m.title, m.releaseDate, m.description, g.name, a.fname, a.lname
FROM movies m
  INNER JOIN movieGenres mg ON m.movieID = mg.movie
  INNER JOIN genres g ON g.genreID = mg.genre
  INNER JOIN movieactors ma on ma.movie  = m.movieID
  INNER JOIN actors a on ma.actor = a.actorID
ORDER BY m.title

如果 actor.movie 和 genres.movie 都匹配 movies.movieID - 这将起作用 - 但通常我喜欢看到外键命名得比这更好。例如,如果Actor.movie真的包含"movieID",则将其命名为"movieID" - 否则我认为我正在寻找

你的问题实际上有两个独立的问题。

1) 如何编写 SQL 查询来获取页面所需的结果。

马克和利都对这个问题有很好的解决方案。就我个人而言,我更喜欢费雯丽的。

我只会在你去的时候添加转储你的结果(这里的所有人都可能知道这一点,但为后代记录下来是一件好事),因为很容易假设你得到的结果与你想象的不一样。

此外,它与下一步特别相关。

2)如何正确显示结果。

为此,您必须了解 cfoutput 的 "group" 属性是如何工作的。它只是检查您选择的列的值是否与上一行相比发生了变化。这意味着您必须按组列排序,否则分组看起来会出错。

例如:

类别,产品

  • 食品, 苹果
  • 清洁工,彗星
  • 食物, 香蕉

如果您对上面的结果这样做,它看起来会出错,因为每次类别切换时都会显示分组输出。另一方面,以下结果集将正常工作:

  • 清洁工,彗星
  • 食品, 苹果
  • 食物, 香蕉

这样做的结果是 cfoutput 组取决于排序,因此您只能在任何一个级别的一列上使用它(当然,您可以根据需要深入多个级别)。

然后,解决方案是更手动地处理第二列分组。例如,这可以通过在某处建立一个列表,然后循环访问它。

因此,对于示例中的查询,这将起作用:

<tbody>
   <cfoutput query="variables.movieList" group="movieId">
       <cfset actors = "">
        <cfoutput>
            <cfif NOT ListFindNoCase(actors,actorId)>
                <cfset actors = ListAppend(actors,actorId)>
            </cfif>
        </cfoutput>
      <tr>
         <td><a href="##">#title#</a></td>
         <td><cfoutput group="name">#name# | </cfoutput></td>
         <td><cfloop list="actors" index="actor">#actor# | </cfloop></td>
      </tr>
   </cfoutput>
</tbody>

不能在同一查询中同时使用演员和流派。最好的办法是只输出带有<cfoutput query="someQry" group="movieId">的电影,然后执行查询查询以分别获取每部电影的演员和流派。

相关内容

  • 没有找到相关文章

最新更新