停止SQL在联接中两次返回相同的结果

停止SQL在联接中两次返回相同的结果,sql,Sql,我将几个表合并在一起以获得所需的数据,但由于我是SQL新手,所以我不知道如何停止多次返回数据 她的SQL语句 SELECT T.url, T.ID, S.status, S.ID, E.action, E.ID, E.timestamp FROM tracks T, status S, events E WHERE S.ID AND T.ID = E.ID ORDER BY E.timestamp DESC 返回的数据是这样的 +-------

我将几个表合并在一起以获得所需的数据,但由于我是SQL新手,所以我不知道如何停止多次返回数据

她的SQL语句

SELECT
   T.url,
   T.ID,

   S.status,
   S.ID,

   E.action,
   E.ID,
   E.timestamp

FROM tracks T, status S, events E
WHERE S.ID AND T.ID = E.ID

ORDER BY E.timestamp DESC
返回的数据是这样的

+----------------------------------------------------------------+
| URL | ID | Status | ID | action               | ID | timestamp |
+----------------------------------------------------------------+
| T.1 | 4  | hello  | 4  | has uploaded a track | 4  | time      |
| T.2 | 3  | bye    | 3  | has some news        | 3  | time      |
| t.1 | 4  | more   | 4  | has some news        | 4  | time      |
+----------------------------------------------------------------+
这是一个非常基本的例子,但确实概述了发生的情况。如果您查看第三行,当出现不同的状态时,URL会重复

这就是我想要发生的事情

+-------------------------------------------------------+
| URL or Status | ID | action               | timestamp |
+-------------------------------------------------------+
| T.1           | 4  | has uploaded a track | time      |
| hello         | 3  | has some news        | time      |
| bye           | 4  | has some news        | time      |
+-------------------------------------------------------+
请注意,当操作上传了一个曲目时,会显示url(在本例中,模拟url是T.1)。这是非常重要的。事件表中的操作是在状态或磁道插入的触发器上插入的。如果插入了新曲目,则操作为“已上载曲目”,您可以猜测其状态。此时,ID和时间戳也被插入到事件表中

注意:查询中有更多的表,事实上还有3个,但为了简单起见,我将它们省略了。

更改此选项

WHERE S.ID AND T.ID = E.ID
对此

WHERE S.ID = E.ID AND T.ID = E.ID
更新


有些人对使用隐式连接表示法非常敏感。为了安抚这些人,作为更好的实践,您应该使用显式的
JOIN
语句。

不要使用20年过时的语法。尽管许多RDBMS支持a、b、c风格的语法,但我使用过的所有系统都不赞成它。(我并没有处理所有问题,但最好不要使用这种风格。)

而是使用ANSI-92标准
JOIN
语法。那就更难出错了

SELECT
  *
FROM
  status S
INNER JOIN
  tracks T
    ON T.ID = S.ID
INNER JOIN
  events E
    ON E.ID = S.ID
ORDER BY
  E.timestamp DESC 
此外,您的示例数据表明,表S中有以下内容

 Status | ID
--------+----
 hello  | 4
 bye    | 3
 more   | 4
ID=4
有两行。如果您真的希望T中的每一行只连接S中的一行,您应该选择哪一行?是否应该删除其中一个,或者您是否有其他逻辑/条件可用于从两个逻辑/条件中选择一个?

尝试使用group by

SELECT T1.url, T1.id, S1.estatus, S1.id, E1.action, E1.id, E1.timestamp FROM t T1, s S1, e E1 WHERE S1.id AND T1.id = E1.id GROUP BY S1.id ORDER BY E1.timestamp DESC;

谢谢你的回答,他们帮了大忙。我用PHP中的if语句进行了一个查询,并对结果进行了操作

在这里

SELECT 
T.url AS track_url,

S.status,

E.action,
E.ID,
E.timestamp,

A.name,
A.url AS artist_url

FROM events E

LEFT JOIN 
TRACKS T
ON T.ID = E.ID AND E.action = 'has uploaded a track.'

LEFT JOIN  
STATUS S
ON S.ID = E.ID AND E.action = 'has some news.'

LEFT JOIN 
ARTISTS A
ON A.ID = E.ID

ORDER BY E.timestamp DESC
它的结果是有很多
NULL
列,但这很好!如果
ID
没有上传曲目,则相关列为
NULL
,这同样适用于查询的其他位。由于只选择了事件表中的
ID
,因此不会重复
ID


如果你看到我可能忽略的任何问题,请大声说出来

这并没有达到预期的效果。不太确定如何解释,但请看一下结果应该是什么样的,以解释需要发生什么。输入
其中T.ID=S.ID和S.ID=E.ID
Aha,那么决定使用
状态而不是
url
的逻辑是什么?根本不要使用a、b、c中的
,其中x
。使用
内部联接
。Ansi-92已经有将近20年的历史了。即使是支持
表示法的RDBMS也不推荐使用它,并建议不要使用它。不要这样做。我会拒绝任何鼓励初学者使用隐式语法的人。这是SQL反模式,我们应该避免推荐使用反模式。因为您是SQL新手,您应该知道隐式联接是SQL反模式,您应该学习使用显式联接。如果可以,我会多次向您推荐。实际上,strill使用隐式语法是没有理由的。但是,并非所有系统都不推荐使用它。在SQL Server中,只有外部连接隐式语法被弃用(而且它从来都不起作用,这也是原因之一)。SQl新手需要理解连接,隐式连接更可能是不正确的,尤其是对于初学者。a、b、c中的
仍然被教授和使用。这也不能解决OP的预期结果。感谢您提供的信息,我不知道它已被弃用。我正在使用的教程使用的是旧的东西。因为它都是在新闻提要中返回的,所以该ID中的每个状态都应该返回,然后按时间戳排序。@njk-请阅读指出
s.ID=4
由两行组成的部分?它表示需要附加逻辑来确定要加入哪一行(或者,可能示例不正确?或者,可能数据需要清理?@Dems如果您阅读我回答中OP的评论,OP不知道他们将如何确定是否使用
状态
vs
url