MySQL需要帮助构建查询:将多个表连接成单个行

4

如果这个问题已经被提出并回答了,那么请原谅我,我已经搜索了一些看起来相似的问题,但是我对SQL还是太菜了,无法将它们适应我的需求。如果我没有使用正确的术语,请也请原谅我,当有人问一个问题时,他们甚至不知道自己需要什么,这可能会很烦人。

<第二次编辑Mar22:>

好吧,我没有理解源数据实际上是什么样子的,这就是为什么我无法得到我想要的东西。感谢@goran推动我获取真正的源表格在这里发布(我仍然不会发布它们,因为我太懒了,无法适当地删除它们以便轻松查看和保护无辜者,但我至少应该在询问之前打印它们)。下面是新修订的示例表格,但我仍然没有弄清楚如何实现将所有内容放入单行的最终目标。

table_one:

id  name          total
5   John Doe      20

表格二:

id  product_id    price
5   51            17

table_three:

id  text       number
5   Subtotal   17
5   Tax        3
5   Total      20

我需要的是这样的东西:
id name     total product_id price text     number text number text   number
5  John Doe 20    51         17    Subtotal 17     Tax  3      Total  20

我不确定下面的信息是否仍然有效,但是我暂时将其保留在这里,希望它不会太过混淆新读者的问题。

</编辑 Mar 22>

我正在帮助一位朋友收集一些数据,并且需要执行一个查询,使其每个记录只返回一行结果,但是实际上我得到了多行结果。以下是我目前正在查询的示例(简化了,希望不要太简单):

SELECT * FROM `table_one` AS t1 
INNER JOIN `table_two` AS t2 ON t1.id = t2.id 
INNER JOIN `table_three` AS t3 ON t1.id = t3.id 
WHERE 1

结果是:
id  text       number
5   Subtotal   17
5   Tax        3
5   Total      20

我需要创建一个查询,使其结果更接近于这样:
id  text       number  text  number  text   number
5   subtotal   17      Tax   3       Total  20

任何帮助和指导都将不胜感激。
谢谢!
--jed

是的,抱歉,我会编辑以澄清。 - Jed Daniels
你引用的查询、结果和样本数据不匹配。为什么不复制粘贴实际的查询和结果呢? 另外,如果你真的想要一个保证明确的答案,你也可以使用mysqldump -c -n database table1 table2 table3 > table.sql命令,然后复制/粘贴相关的INSERTS和CREATE TABLE语句的相关部分(如果不太长的话)。 - Unreason
@goran:好的,我只是试图获取真实的表格,这让我看到了我的错误。我曾经错误地认为每个表格都有一个我想要组合的不同元素,但是一个表格有多个行需要被组合,这就是事情没有按照我预期的方式发展的原因。故事的寓意是:在假设结果不正确之前,请确保您了解源数据的样子。我将很快更新问题并提供更多信息。 - Jed Daniels
啊,那么ID在那里并不是真正的主键 :) 这也使跟踪变得困难...无论如何,更新一下,我们再试试。 - Unreason
@goran,我已经更新了最新的内容(基本上替换了我上次更新的内容)。我知道我在这方面是个新手,感谢你一直陪伴着我。最坏的情况是我只能单独输出三个表格,并用Python或Bash脚本将它们组合成我想要的方式,但我更希望对MySQL有更深入的了解。 - Jed Daniels
显示剩余2条评论
3个回答

4

我认为你在某些地方过于简化了它。 你引用的查询语句已经可以返回你想要的结果了。 这里有一个例子(从单个表中选择两次会产生与你所拥有的情况类似的情况)。

mysql> select * from test t1 join test t2 on t1.a = t2.a LIMIT 1,5;
+------+------+------+------+
| a    | b    | a    | b    |
+------+------+------+------+
|    1 |    2 |    1 |    1 | 
|    1 |    1 |    1 |    2 | 
|    1 |    2 |    1 |    2 | 
|    2 |    2 |    2 |    2 | 
|    2 |    2 |    2 |    2 | 
+------+------+------+------+
5 rows in set (0.00 sec)

MySQL没有问题将结果集列标记为相同的标签。 我猜你原始的查询在select部分有select t1.*。 如果你想引用名称不明确的单个字段,你会得到…
mysql> select a from test t1 join test t2 on t1.a = t2.a LIMIT 1,5;
ERROR 1052 (23000): Column 'a' in field list is ambiguous

你需要明确指定你想要的内容(列别名是可选的,你也可以使用 t1.、t2. 等方式)

mysql> select t1.a first, t2.a second from test t1 join test t2 on t1.a = t2.a LIMIT 1,5;
+-------+--------+
| first | second |
+-------+--------+
|     1 |      1 | 
|     1 |      1 | 
|     1 |      1 | 
|     2 |      2 | 
|     2 |      2 | 
+-------+--------+
5 rows in set (0.00 sec)

编辑 22MAR 在样本数据发生变化后,似乎您想要将一个表格中的多行合并成一行。 以下是一种特定的解决方案(假设您始终拥有税、总计和小计行,并且您只对这些行感兴趣)。

SELECT t1.id, t1.name, t2.product_id, t2.price, t3a.number subtotal, t3b.number total, t3c.number tax
FROM `table_one` AS t1 
INNER JOIN `table_two` AS t2 ON t1.id = t2.id 
INNER JOIN `table_three` AS t3a ON t1.id = t3a.id and t3a.text = "Subtotal"
INNER JOIN `table_three` AS t3b on t3a.id = t3b.id and t3b.text = "Total"
INNER JOIN `table_three` AS t3c on t3b.id = t3c.id and t3c.text = "Tax"

(如果您希望,您也可以在选择部分中选择常量“税”,“总计”和“小计”,并为它们指定一些列名称)

仍然不清楚的一件事是表格中id之间的关系 - 它们是table_one或table_two的主键。当table_one和table_two中有多行时,这当然会影响结果。


我并没有真正简化查询,只是简化了结果(实际结果有大约50列),尽管我更改了表的名称以使事情变得更容易(它们的名称是orders、orders_total和orders_products)。我不确定我完全理解你的例子,因为第一个明显是从单个表中选择,而我正在尝试将三个表的输出合并在一起(消除相等的重复项并复制不相等的重复项)。谢谢,--jed - Jed Daniels
我的例子展示了a) mysql客户端中列名相同标签没有问题 b) 如何使用别名。 - Unreason
@gordan: "有一件事仍然不清楚,那就是表格中id之间的关系 - 它们是table_one或table_two的主键吗?" 我真的不知道。我相当确定table_one和table_two每个id只有一行。再次感谢您的回答,我相信我可以让您修改后的示例工作,这样就可以解决我的问题,而无需进行任何其他脚本编写。--jed - Jed Daniels
很高兴能帮忙,但是如果你不知道你的表格之间的关系,你就不能说你走在正确的轨道上。 :) - Unreason

1

由于您有相同名称的列,因此您将无法完全按照所需方式获取结果。可能您可以通过重命名列来获得此结果,但这种方法会导致代码不规范且无法正确使用结果。

您应该重新考虑返回记录的进一步使用,并更新它以便在 SQL select 正常返回数据时立即处理实际结果。


1

你所要求的输出不是一个关系,因为它的属性没有唯一的名称。因此,期望关系数据库系统产生这样的结果是不合理的。这并不是说某些数据库系统不能在某些情况下打破关系模型并产生非关系结果;但这不太可能是其中之一。

因此,你应该让应用程序将关系作为输入并将其转换为所需的输出。从关系数据库管理系统的角度来看,这是应用程序的主要部分。


我可以接受这个答案,并且愿意用脚本转换数据,但如果有一种方法可以使MySQL以接近我所需的方式输出内容,那将是最好的。非常感谢,--jed - Jed Daniels

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接