选择另外两个表中的行数

时间:2018-01-04 09:31:52

标签: sql

我有3张桌子。我想要检索一些信息的主要信息和另外两个仅用于行数的信息。

我使用了这样的请求:

SELECT A.*,
    COUNT(B.id) AS b_count
FROM A
    LEFT JOIN B on B.a_id = A.id
WHERE A.id > 50 AND B.ID < 100
GROUP BY A.id

来自Gerry Shaw的评论here。它完美无缺,但只适用于一张桌子。

现在我需要为第三个(C)表添加行计数。我试过了

SELECT A.*,
    COUNT(B.id) AS b_count
    COUNT(C.id) AS c_count
FROM A
    LEFT JOIN B on B.a_id = A.id
    LEFT JOIN C on C.a_id = A.id
GROUP BY A.id

但是,由于左边两个连接,我的b_count和我的c_count都是假的并且彼此相等。实际上,我的实际b_countc_count等于real_b_count*real_c_count。知道如何在不添加大量复杂性/子查询的情况下解决这个问题吗?

按要求提供数据样本:

Table A (primary key : id)
id    | data1 | data2
------+-------+-------
1     |  0,45 |  0,79
----------------------
2     | -2,24 | -0,25
----------------------
3     |  1,69 |  1,23

Table B (primary key : (a_id,fruit))
a_id  | fruit
------+-------
1     | apple
------+-------
1     | banana
--------------
2     | apple

Table C (primary key : (a_id,color))
a_id  | color
------+-------
2     | blue
------+-------
2     | purple
--------------
3     | blue

预期结果:

id    | data1 | data2 | b_count | c_count
------+-------+-------+---------+--------
1     |  0,45 |  0,79 | 2       | 0
----------------------+---------+--------
2     | -2,24 | -0,25 | 1       | 2
----------------------+---------+--------
3     |  1,69 |  1,23 | 0       | 1

5 个答案:

答案 0 :(得分:2)

有两种可能的解决方案。一个是使用SELECT

后面的子查询
SELECT A.*,
    (
       SELECT COUNT(B.id) FROM B WHERE B.a_id = A.id AND B.ID < 100
    ) AS b_count,
    (
       SELECT COUNT(C.id) FROM C WHERE C.a_id = A.id
    ) AS c_count
FROM A
WHERE A.id > 50

第二个是连接在一起的两个SQL查询

SELECT t1.*, t2.c_count
FROM
(
    SELECT A.*,
        COUNT(B.id) AS b_count
    FROM A
        LEFT JOIN B on B.a_id = A.id
    WHERE A.id > 50 AND B.ID < 100
    GROUP BY A.id
) t1
JOIN
(
    SELECT A.*,
        COUNT(C.id) AS c_count
    FROM A
        LEFT JOIN C on C.a_id = A.id
    WHERE A.id > 50
    GROUP BY A.id
) t2 ON t1.id = t2.id

我更喜欢第二种语法,因为它清楚地显示了您对GROUP BY感兴趣的优化器,但查询计划通常是相同的。

答案 1 :(得分:1)

如果表B&amp; C也有自己的关键字段,那么你可以在主键而不是外键上使用COUNT DISTINCT。这可以解决您在链接到多个表时看到的多线问题。如果您可以发布表结构,那么我们可以进一步建议。

答案 2 :(得分:1)

这是我能想到的更容易的方式:

    import re
    a='https://abcd.sample.com/templates/cp/assets/img/1_fs?123456'
    result=re.search(r'^https:\/\/abcd.sample.com\/[a-z,\/]*1_fs\?123456$',a)
    print result

结果:

Create table #a (id int, data1 float, data2 float)
Create table #b (id int, fruit varchar(50))
Create table #c (id int, color varchar(50))

Insert into #a
SELECT 1, 0.45, 0.79
UNION ALL SELECT 2, -2.24, -0.25
UNION ALL SELECT 3,  1.69, 1.23

Insert into #b
SELECT 1, 'apple'
UNION ALL SELECT 1, 'banana'
UNION ALL SELECT 2, 'orange'


Insert into #c
SELECT 2, 'blue'
UNION ALL SELECT 2, 'purple'
UNION ALL SELECT 3, 'orange'



SELECT #a.*,
    (SELECT COUNT(#b.id) FROM #b where #b.id = #a.id) AS b_count,
    (SELECT COUNT(#c.id) FROM #c where #c.id = #a.id) AS b_count
FROM #a
ORDER BY #a.id

答案 3 :(得分:1)

尝试这样的事情

SELECT A.*,
       (SELECT COUNT(B.id) FROM B WHERE B.a_id = A.id) AS b_count,
       (SELECT COUNT(C.id) FROM C WHERE C.a_id = A.id) AS c_count
FROM A

答案 4 :(得分:1)

如果表b和c具有唯一ID,您可以尝试:

SELECT A.*,
    COUNT(distinct B.fruit) AS b_count,
    COUNT(distinct C.color) AS c_count
FROM A
    LEFT JOIN B on B.a_id = A.id
    LEFT JOIN C on C.a_id = A.id
GROUP BY A.id

请参阅SQLFiddle MySQL demo