停止SQL在联接中两次返回相同的结果
我将几个表合并在一起以获得所需的数据,但由于我是SQL新手,所以我不知道如何停止多次返回数据 她的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 返回的数据是这样的 +-------
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不知道他们将如何确定是否使用状态
vsurl
。