为什么我不能在子查询中选择多个列?

时间:2016-05-10 13:03:48

标签: mysql sql subquery mariadb

我一直在做这个查询

SELECT
    A.*,
    (
        SELECT
            SUM(IF(LENGTH(B.picture) > 0, 1, 0)) AS A_picture_count,
            SUM(IF(LENGTH(B.video) > 0, 1, 0)) AS A_video_count
        FROM B
        WHERE B.A_id = A.id
    )
FROM A

Operand should contain 1 column(s)

回答我
SELECT
    A.*,
    (
        SELECT
            SUM(IF(LENGTH(B.picture) > 0, 1, 0)) AS A_picture_count
        FROM B
        WHERE B.A_id = A.id
    )
FROM A

完美无缺。为什么MariaDB不会让我超过1列子查询?我错过了什么吗?

正如这个问题(MySQL - Operand should contain 1 column(s))所暗示的那样,

你可能会回答我应该这样做

SELECT t1.*, sq.*
FROM table1 t1,
   (SELECT a,b,c FROM table2 ...) sq
WHERE ...

或使用连接(但我的查询要复杂得多,而且我的很多SUMS和COUNTS在我的GROUP BY中乱七八糟。)

我的问题更多的是关于“为什么”而不是“如何”。

我的最终解决方案(不是最佳的):

SELECT
    A.*,
    (
        SELECT
            SUM(IF(LENGTH(B.picture) > 0, 1, 0)) AS A_picture_count,
        FROM B
        WHERE B.A_id = A.id
    )
    (
        SELECT
            SUM(IF(LENGTH(B.video) > 0, 1, 0)) AS A_video_count
        FROM B
        WHERE B.A_id = A.id
    )
FROM A

2 个答案:

答案 0 :(得分:2)

一个令人愤慨的黑客将两个值编码为一个变量。假设这两个数字都不能超过1000:

SELECT
    A.*,
    (
        SELECT
         1000 * SUM(IF(LENGTH(B.picture) > 0, 1, 0)) +
                SUM(IF(LENGTH(B.video) > 0, 1, 0)) AS A_pv_count
        FROM B
        WHERE B.A_id = A.id
    )
FROM A

您可以使用 / 1000 %1000

重新获取组件
SELECT floor(A_pv_count / 1000) AS A_picture_count,
            (A_pv_count % 1000) AS A_video_count
FROM
(SELECT
    A.*,
    (
        SELECT
         1000 * SUM(IF(LENGTH(B.picture) > 0, 1, 0)) +
                SUM(IF(LENGTH(B.video) > 0, 1, 0)) AS A_pv_count
        FROM B
        WHERE B.A_id = A.id
    )
 FROM A) AS AW

答案 1 :(得分:1)

IMO无数据库应该允许您选择( )中的两列。显然你不能做select col1, (col2_ok), (multi_columns_HOW_ON_EARTH?)

一个解决方案应该是使用这样的tmp表(已搜索但MariaDB不支持cte):

select A.*, tmp.A_picture_count, tmp.A_video_count
from A
inner join (SELECT A.id,
                SUM(IF(LENGTH(B.picture) > 0, 1, 0)) AS A_picture_count,
                SUM(IF(LENGTH(B.video) > 0, 1, 0)) AS A_video_count
            FROM A
            inner join B
            on B.A_id = A.id
            group by A.id
            ) tmp
on A.id = tmp.id;