【问题标题】:SQL: Combining 2 rows to one from 1 table results in more than one row for subquerySQL:将1个表中的2行合并为1行导致子查询多行
【发布时间】:2013-04-22 18:57:44
【问题描述】:

我有什么:

一桌水果 食物(我从中选择水果),每个水果两排,小号一排,大号一排。

id | category | subcategory | title  | description       | value
-----------------------------------------------------------------
1  | Fruit    | Small       | Plum   | Om, nom, nom!     | 0.50
2  | Fruit    | Large       | Plum   | Om, nom, nom!     | 1.50
3  | Fruit    | Small       | Orange | Mmm, citrus.      | 0.30
4  | Fruit    | Large       | Orange | Mmm, citrus.      | 0.75
5  | Fruit    | Small       | Melon  | Get in mah belly! | 2.00
6  | Fruit    | Large       | Melon  | Get in mah belly! | 3.10

我需要什么:

我需要将每个水果的两行合并为一行:

categorytitledescription 对于每对行将始终相同。

idsubcategoryvalue 对于每对行总是不同的。

id.r1 | id.r2 | category.r1 |  title.r1  | description.r1       | subcategory.r1 | value.r1 | subcategory.r2 | value.r2
-----------------------------------------------------------------------------------------------------------------------
1     | 2     | Fruit       |  Plum      | Om, nom, nom!        | Small          | 0.50     | Large          | 1.50
3     | 4     | Fruit       |  Orange    | Mmm, citrus.         | Small          | 0.30     | Large          | 0.75
5     | 6     | Fruit       |  Melon     | Get in mah belly!    | Small          | 2.00     | Large          | 3.10

我尝试过的:

SELECT r1.id,
(SELECT r2.id FROM `my_table` r2 WHERE r1.title = r2.title),  
r1.category, 
r1.subcategory,
(SELECT r2.category FROM `my_table` r2 WHERE r1.title = r2.title) 
r1.title, 
r1.description, 
r1.value, 
(SELECT r2.value FROM `my_table` r2 WHERE r1.title = r2.title)

FROM `my_table` r1

WHERE category = "Fruit"

...产生:

子查询返回多于 1 行

我的问题:

我应该如何修改上述查询以实现我所描述的?

【问题讨论】:

    标签: mysql sql database phpmyadmin


    【解决方案1】:

    您可以通过聚合轻松做到这一点:

    select category, title, description,
           MAX(case when subcategory = 'Small' then id end) as Small_Id,
           MAX(case when subcategory = 'Small' then value end) as Small_Value,
           MAX(case when subcategory = 'Large' then id end) as Large_Id,
           MAX(case when subcategory = 'Large' then value end) as Large_Value
    from my_table f
    group by category, title, description
    

    注意:这在最终结果中不包括 subcategory,因为该行没有子类别。

    您也可以将其作为连接来执行,这似乎是您所采取的路径:

    select fsmall.id, flarge.id, fsmall.category, flarge.category, . . .
    from my_table fsmall join
         my_table flarge
         on fsmall.subcategory = 'small' and flarge.subcategory = 'large' and
            fsmall.category = flarge.category and
            fsmall.title = flarge.title and
            fsmall.description = flarge.description
    

    根据您是否可能缺少某些行,您可能需要left outer joinfull outer join

    【讨论】:

    • 感谢您选择解决方案和每一个解释。解决方案 1:这非常有效。我明白你对子类别的意思。子类别值改为在 id 和值的列标题中表示。解决方案 2:我无法正确地凭直觉确认它是否有效以及生成的行是否相同。 “fruit”(类别值)不应该是“my_table”(表的名称)还是我离题了?另外,省略号(...)是功能性的还是我假设要添加其他列?非常感谢您的帮助。
    • @DominorNovus 。 . .我称该表为fruit,但我只是在您的问题中将其替换为my_table。这能解决您的问题吗?
    • 好的,谢谢。我修改了第二个解决方案的列选择,并在查询末尾添加了 WHERE 条件。最终结果产生的记录数量与第二种解决方案完全相同。修改后的代码:pastebin.com/1BDfWbC9
    • 是否有可能使用第二个选项,但让第一个连接的表没有名称?因为我需要编辑现有的查询并且我不能添加像“fsmall”这样的前缀。在每一列之前... => 类似“..from my_table join my_table flarge..”
    • @LukasSalich 。 . .我真的不明白这个问题。最好将新问题作为问题而不是在评论中提出。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-26
    • 2022-01-13
    相关资源
    最近更新 更多