1

我已经将几个表连接在一起以获取我想要的数据,但是由于我是 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(在本例中模拟的是 T.1)。这个非常重要。在触发状态或轨道插入时插入事件表中的操作。如果插入了新曲目,则操作是“已上传曲目”,您猜它是什么状态。此时,ID 和时间戳也被插入到事件表中。

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

4

4 回答 4

2

不要使用 20 年过时的语法。尽管许多 RDBMS 支持FROM 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 中的一行,您应该选择哪一行?应该删除一个,还是您有其他一些逻辑/条件可以用来选择两者之一?

于 2012-08-31T15:31:41.090 回答
0

改变这个

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

对此

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

更新

有些人对使用隐式连接表示法非常敏感。为了安抚这些人并作为更好的做法,您应该使用明确JOIN的陈述。

于 2012-08-31T14:55:56.030 回答
0

尝试使用分组;

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;
于 2012-08-31T15:37:20.880 回答
0

感谢所有的答案,他们帮助了很多。我已经使用 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了事件表中的 。

如果您发现我可能忽略的任何问题,请大声疾呼!

于 2012-08-31T16:45:25.873 回答