为什么我的子查询中不能 select 超过一列?

Why I can't select more than one column in my subquery?

我一直在做这个查询

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 混在一起)。

我的问题更多是关于 "Why" 而不是 "How"。


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

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

一个离谱的 hack 是将两个值编码到一个变量中。假设两个数字都不能超过 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

IMO No Database 应该让你 select 像这样在 ( ) 中有两列。很明显你不能做 select col1, (col2_ok), (multi_columns_HOW_ON_EARTH?)

一个解决方案应该是像这样使用 tmp table(已搜索但 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;