Могу ли я выбрать все и сосчитать все из объединения в одном операторе MySQL? - PullRequest
0 голосов
/ 07 апреля 2020

У меня есть оператор SELECT, который возвращает записи из нескольких таблиц. Вот схема c:

select * from `tbl1` where `cond1`='something2'
UNION ALL
select * from `tbl2` where `cond2`='something2'
UNION ALL
-- etc
select * from `tblN` where `condN`='somethingN'
ORDER BY `sortColumn` ASC
LIMIT 0, 15

Мне также нужно знать общее количество всех строк. Так что я могу сделать:

SELECT count(*) as cntAll FROM(
    select * from `tbl1` where `cond1`='something2'
    UNION ALL
    select * from `tbl2` where `cond2`='something2'
    UNION ALL
    -- etc
    select * from `tblN` where `condN`='somethingN'
) as x;

Это также отлично работает.

Но могу ли я объединить два в одно утверждение?

Если я попробую это, он просто вернет один строка:

SELECT *, count(*) as cntAll FROM(
    select * from `tbl1` where `cond1`='something2'
    UNION ALL
    select * from `tbl2` where `cond2`='something2'
    UNION ALL
    -- etc
    select * from `tblN` where `condN`='somethingN'
    ORDER BY `sortColumn` ASC
    LIMIT 0, 15
) as x;

PS. Я пользуюсь MySQL v.5.7.28

1 Ответ

0 голосов
/ 07 апреля 2020

Учитывая

+------+--------+--------+--------+--------+------------+------+
| ID   | userid | FNAME  | sname  | email  | dob        | IX   |
+------+--------+--------+--------+--------+------------+------+
|    1 |      1 | fname1 | sname1 | email1 | 2000-01-01 |    6 |
|    2 |      2 | fname2 | sname2 | email2 | 2000-01-01 |    5 |
|    3 |      3 | fname3 | sname3 | email3 | 2000-01-01 |    4 |
|    4 |      4 | fname4 | sname4 | email4 | 2000-01-01 |    3 |
|    5 |      5 | fname5 | sname5 | email5 | 2000-01-01 |    2 |
|    6 |      6 | fname6 | sname6 | email6 | 2000-01-01 |    1 |
+------+--------+--------+--------+--------+------------+------+
6 rows in set (0.001 sec)

Тогда вы можете прочитать объединение дважды, чтобы получить строки, во-вторых, чтобы получить счет, используя перекрестное соединение

select a.* , b.cnt
from 
(select * from users t1
union all
select * from users t2
union all
select * from users t3
order by id limit 0,15
) a
cross join
(
select count(*)  cnt
from
(
select * from users t1
union all
select * from users t2
union all
select * from users t3
order by id limit 0,15
) s
) b;

+------+--------+--------+--------+--------+------------+------+-----+
| ID   | userid | FNAME  | sname  | email  | dob        | IX   | cnt |
+------+--------+--------+--------+--------+------------+------+-----+
|    1 |      1 | fname1 | sname1 | email1 | 2000-01-01 |    6 |  15 |
|    1 |      1 | fname1 | sname1 | email1 | 2000-01-01 |    6 |  15 |
|    1 |      1 | fname1 | sname1 | email1 | 2000-01-01 |    6 |  15 |
|    2 |      2 | fname2 | sname2 | email2 | 2000-01-01 |    5 |  15 |
|    2 |      2 | fname2 | sname2 | email2 | 2000-01-01 |    5 |  15 |
|    2 |      2 | fname2 | sname2 | email2 | 2000-01-01 |    5 |  15 |
|    3 |      3 | fname3 | sname3 | email3 | 2000-01-01 |    4 |  15 |
|    3 |      3 | fname3 | sname3 | email3 | 2000-01-01 |    4 |  15 |
|    3 |      3 | fname3 | sname3 | email3 | 2000-01-01 |    4 |  15 |
|    4 |      4 | fname4 | sname4 | email4 | 2000-01-01 |    3 |  15 |
|    4 |      4 | fname4 | sname4 | email4 | 2000-01-01 |    3 |  15 |
|    4 |      4 | fname4 | sname4 | email4 | 2000-01-01 |    3 |  15 |
|    5 |      5 | fname5 | sname5 | email5 | 2000-01-01 |    2 |  15 |
|    5 |      5 | fname5 | sname5 | email5 | 2000-01-01 |    2 |  15 |
|    5 |      5 | fname5 | sname5 | email5 | 2000-01-01 |    2 |  15 |
+------+--------+--------+--------+--------+------------+------+-----+
15 rows in set (0.002 sec)
...