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

时间:2010-03-20 23:37:20

标签: sql mysql mysql-error-1052

请原谅我,如果这个问题已被提出并回答,我已经搜索过并找到了一些看似相似的东西,但我对SQL的新手太过适应我的需求了。如果我不使用正确的术语,也请原谅我,我知道当有人问一个问题并且他们甚至不知道能够询问他们需要什么时,这可能会很烦人。

<第二次编辑Mar22:>

好的,我不明白源数据实际上是什么样的,这就是为什么我无法得到我想要的东西。感谢@goran推动我在这里发布真正的源表(我仍然不会发布,因为我太懒于编辑它们以便于查看和保护无辜者,但我应该有至少在问之前将它们打印出来)。下面是新修订的示例表,但我仍然没有弄清楚如何实现将所有内容放入一行的最终目标。

table_one:

id  name          total
5   John Doe      20

table_two:

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

我不再确定以下信息的有效性,但我暂时将其留在这里,希望它不会过多地混淆新问题的读者。

< / EDIT 3月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

3 个答案:

答案 0 :(得分: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)

使用相同的标签标记结果集列没有问题。 我猜你的原始查询在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 在更改示例数据后,您似乎希望将一个表中的多行转换为一个。 这是一个特殊的解决方案(假设您总是有Tax,Total和Subtotal行,并且您只对这些行感兴趣)。

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"

(如果你想要你也可以在选择部分中选择常数“Tax”,“Total”和“Subtotal”并给它们一些列名称)

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

答案 1 :(得分:1)

至少因为你有相同名称的列,你将无法完全按照自己的意愿获得结果。可能你可能会在重命名的列中得到这个结果,但这种方法会导致hacky代码和无法正确使用结果。

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

答案 2 :(得分:1)

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

所以你应该让应用程序将关系作为输入并将其转换为你想要的输出。从RDBMS的角度来看,这是应用程序角色的主要部分。