Что не так в этом запросе? - PullRequest
0 голосов
/ 02 августа 2011

Я выбираю общее количество деревень, общее количество населения из моих таблиц для построения статистики.Однако что-то не так.Он возвращает мне все (530 поп (всего 530 поп), (106 деревень (всего 106 пользователей)) в первой строке, следующие строки - NULL

enter image description here

SELECT s1_users.id userid, (

SELECT count( s1_vdata.wref ) 
FROM s1_vdata, s1_users
WHERE s1_vdata.owner = userid
)totalvillages, (

SELECT SUM( s1_vdata.pop ) 
FROM s1_users, s1_vdata
WHERE s1_vdata.owner = userid
)pop
FROM s1_users
WHERE s1_users.dp >=0
ORDER BY s1_users.dp DESC

Ответы [ 4 ]

2 голосов
/ 02 августа 2011

Вы уже используете ВНУТРЕННИЕ СОЕДИНЕНИЯ. Когда вы перечисляете таблицы, разделенные запятой, это ярлык для INNER JOIN.

Теперь наиболее очевидный ответ заключается в том, что в ваших подзапросах, использующих функции агрегирования (COUNT и SUM), отсутствуют предложения GROUP BY.

SELECT s1_users.id userid, (

SELECT count( s1_vdata.wref ) 
FROM s1_vdata, s1_users
WHERE s1_vdata.owner = userid
GROUP BY s1_vdata.owner
)totalvillages, (

SELECT SUM( s1_vdata.pop ) 
FROM s1_users, s1_vdata
WHERE s1_vdata.owner = userid
GROUP BY s1_vdata.owner
)pop
FROM s1_users
WHERE s1_users.dp >=0
ORDER BY s1_users.dp DESC

Однако использование подзапросов в списке столбцов действительно неэффективно. Подзапросы запускаются один раз для каждой строки во внешнем запросе.

Попробуйте вместо этого

SELECT 
  s1_users.id AS userid,
  COUNT(s1_vdata.wref) AS totalvillages,
  SUM(s1.vdata.pop) AS pop
FROM
  s1_users, s1_vdata  --I'm cheating here! There's hidden INNER JOIN in this line ;P
WHERE
  s1_users.dp >= 0
  AND s1_users.id = s1_vdata.owner
GROUP BY
  s1_users.id
ORDER BY
  s1_users.dp DESC
2 голосов
/ 02 августа 2011

Попробуйте удалить s1_users из внутренних SELECTS

0 голосов
/ 02 августа 2011
SELECT userid,totalvillages,pop   from 
(
SELECT s1_users.id as userid, count( s1_vdata.wref ) as totalvillages
FROM s1_vdata, s1_users
WHERE s1_vdata.owner = userid
GROUP BY s1_users.id) tabl1 INNER JOIN
(
SELECT s1_users.id as userid, SUM( s1_vdata.pop )  as pop
FROM s1_users, s1_vdata
WHERE s1_vdata.owner = userid
GROUP BY s1_users.id) tabl2 on tabl1.userid = tabl2.userid
0 голосов
/ 02 августа 2011
SELECT  s1_users.id AS userid,
        (
        SELECT  COUNT(*)
        FROM    s1_vdata
        WHERE   s1_vdata.owner = userid
        ) AS totalvillages,
        (
        SELECT  SUM(pop)
        FROM    s1_vdata
        WHERE   s1_vdata.owner = userid
        ) AS pop
FROM    s1_users
WHERE   dp >= 0
ORDER BY
        dp DESC

Обратите внимание, что это менее эффективно, чем этот запрос:

SELECT  s1_users.id AS user_id, COUNT(s1_vdata.owner), SUM(s1_vdata.pop)
FROM    s1_users
LEFT JOIN
        s1_vdata
ON      s1_vdata.owner = s1_users.id
GROUP BY
        s1_users.id
ORDER BY
        dp DESC

, поскольку в первом случае агрегирование необходимо выполнить дважды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...