mysql - два левых соединения - двойной счет - PullRequest
1 голос
/ 08 октября 2011

Долгое время пользователь, первый раз постер.Я нашел похожие вопросы / ответы, как правило, связанные с подзапросами, но я не уверен, как применить к моей ситуации.

У меня есть 3 таблицы:

table1
id

table2
id | val (each id has 1 of 3 possible values)

table3
id | val (each id has 1 of 3 possible values)

РЕДАКТИРОВАТЬ: Пример: (table1 = уникальный идентификатор всех, кто посещал тематический парк; table2 = какой аттракцион посетил каждый посетитель первым; table3 = какой аттракционкаждый посетитель посетил второго).

Я хочу написать запрос для поиска 7 различных счетчиков: (1) количество уникальных идентификаторов в таблице1 (2) количество идентификаторов, которые имеют каждое из возможных значений в таблице2 (3)количество идентификаторов, которые имеют каждое из возможных значений в таблице 3

Мой запрос MySQL:

SELECT 
    count(DISTINCT table1.id) AS x1, 
    SUM(IF(table2.val='1'),1,0)) AS x2, 
    SUM(IF(table2.val='2'),1,0)) AS x3, 
    SUM(IF(table2.val='3'),1,0)) AS x4, 
    SUM(IF(table3.val='1'),1,0)) AS x5, 
    SUM(IF(table3.val='2'),1,0)) AS x6, 
    SUM(IF(table3.val='3'),1,0)) AS x7 
FROM 
    table1 
LEFT JOIN 
    table2 ON table1.id=table2.id 
LEFT JOIN 
    table3 ON table1.id=table3.id 

Результаты:

x1 = правильно (из-за DISTINCT)

x2, x3, x4 = правильно

x5, x6, x7 = ДВАЖДЫ число, которое они должны быть (потому что я получаю декартово произведение?)

Есть предложения?

Ответы [ 3 ]

2 голосов
/ 09 октября 2011

Вы получаете декартово результат.Так как вы не показываете, сколько «1», «2» или «3» считает за «ID», просто сделайте select sum () из этих таблиц сами по себе.Поскольку сумма без группы по всегда приводит к ОДНОЙ записи, вам не нужно объединение, и она будет извлекать результаты по одной записи на каждую сводку без декартовых результатов.Так как ваш исходный запрос был LEFT JOIN для других, идентификатор уже существовал бы в таблице 1, так что зачем повторно запрашивать количество в каждой вложенной таблице.

SELECT
      SumForTable1.x1, 
      SumForTable2.x2,
      SumForTable2.x3,
      SumForTable2.x4,
      SumForTable3.x5,
      SumForTable3.x6,
      SumForTable3.x7
   FROM 
      ( select count(DISTINCT table1.id) AS x1
           from table1 ) SumForTable1,

      ( select SUM(IF(table2.val='1'), 1, 0)) AS x2, 
               SUM(IF(table2.val='2'), 1, 0)) AS x3, 
               SUM(IF(table2.val='3'), 1, 0)) AS x4
            from table2 ) SumForTable2,

      ( select SUM(IF(table3.val='1'), 1, 0)) AS x5, 
               SUM(IF(table3.val='2'), 1, 0)) AS x6, 
               SUM(IF(table3.val='3'), 1, 0)) AS x7
            from table3 ) SumForTable3
1 голос
/ 08 октября 2011

Я думаю, вы проблема в том, что идентификатор не уникален в table1. Таким образом, несмотря на то, что она уникальна в table2/3 (согласно вашему описанию), каждая строка в table2/3 объединяется в две строки в table1 и, таким образом, учитывается дважды. Не имеет ничего общего с левыми объединениями, обычные внутренние объединения будут иметь такую ​​же проблему.

Если mysql (который я не очень хорошо знаю) позволяет вам делать встроенные представления, как это делает oracle, то вы можете исправить это, написав свой запрос как:

SELECT 
    count(view1.id)              AS x1, 
    SUM(IF(table2.val='1'),1,0)) AS x2, 
    SUM(IF(table2.val='2'),1,0)) AS x3, 
    SUM(IF(table2.val='3'),1,0)) AS x4, 
    SUM(IF(table3.val='1'),1,0)) AS x5, 
    SUM(IF(table3.val='2'),1,0)) AS x6, 
    SUM(IF(table3.val='3'),1,0)) AS x7 
FROM 
    (  SELECT DISTINCT table1.id
       FROM   table1
    ) view1
LEFT JOIN 
    table2 ON view1.id=table2.id 
LEFT JOIN 
    table3 ON view1.id=table3.id
0 голосов
/ 09 октября 2011

Я бы удалил дубликаты на каждой таблице:

SELECT
    count(t1.id) AS t1, 
    SUM(IF(t2.val=1,1,0)) AS t21, 
    SUM(IF(t2.val=2,1,0)) AS t22, 
    SUM(IF(t2.val=3,1,0)) AS t23, 
    SUM(IF(t3.val=1,1,0)) AS t31, 
    SUM(IF(t3.val=2,1,0)) AS t32, 
    SUM(IF(t3.val=3,1,0)) AS t33
FROM (SELECT DISTINCT * FROM table1) as t1
JOIN (SELECT DISTINCT * FROM table2) as t2 ON t1.id=t2.id 
JOIN (SELECT DISTINCT * FROM table3) as t3 ON t1.id=t3.id;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...