2016-01-20 6 views
1

Я сделал неудачную попытку объединить значения из двух разных таблиц. Первый отображается так, как хотелось бы, но второй отображает только первую строку каждый раз.Слияние двух таблиц без использования соединения в mysql?

Select * From (Select date as Date, Sum(qty) as qtySum, Sum(weight) 
as weightSum From stock_list Group by date) as A, 
(Select Sum(weight) as weightSum,Count(barcode) 
as barcodeCount From selected_items Group by date) as B Group by date; 

Это выход, который я получаю.

enter image description here

Это мой стол selected_items.

enter image description here

Это мой stock_list. enter image description here

Оба моих запроса работают индивидуально, и я получаю правильный вывод только тогда, когда я пытаюсь запустить их вместе, это создает проблему для второго запроса. Кто-нибудь может указать на мою ошибку или показать мне лучший способ сделать это. Это моя конечная цель: enter image description here

+0

Спасибо @Jens вы можете помочь с решением. – AndroidNewBee

+0

Почему вы не используете соединения? – Jens

+0

Почему вы не используете оператор 'JOIN'? Просто FULL JOIN результаты из таблицы A и таблицы B через столбец даты. – fabulaspb

ответ

1

Первая проблема заключается в том, что вы группировка по дате в вашем подзапрос B, но вы не выбрали его, так что ваш набор результатов может быть что-то вроде:

weightSum  barcodeCount 
--------------------------- 
26    8 
9    14 
4    7 

Это результат для 3 дат, но вы не знаете, к какой дате относится эта строка.

Ваша следующая проблема состоит в том, что вы используете крест присоединиться, потому что нет никакой связи между вашими двумя запросами, это означает, что если ваш первый запрос возвращает:

Date   qtySum  weightSum 
---------------------------------------- 
2016-01-20  1   1 
2016-01-21  2   2 

После того, как вы сделали это крест присоединиться к вам концу вверху:

Date   qtySum  a.weightSum  b.weightSum  barcodeCount 
-------------------------------------------------------------------------- 
2016-01-20  1   1    26    8 
2016-01-20  1   1    9    14 
2016-01-20  1   1    4    7 
2016-01-21  2   2    26    8 
2016-01-21  2   2    9    14 
2016-01-21  2   2    4    7 

Таким образом, каждая строка из А соответствует каждой строке из В, дающей вам 6 полных строк.

Ваша третья проблема заключается в том, что вы затем группируете по дате, но не выполняете каких-либо агрегатов, не вдаваясь слишком много в мелкий шрифт стандарта SQL, предложение group by и функциональную зависимость, упрощаете его в MySQL позволяет это, но вы не должны этого делать, если не понимаете ограничений (это более подробно описано в этом вопросе в this answer). Все, что находится в элементе select, которое не находится в предложении group by, должно быть, должно быть в пределах совокупности.

Итак, из-за расширения GROUP BY Extension MySQL, выбирая все и группируя только по дате, то, что вы эффективно говорите, занимает 1 строку на дату, но у вас нет контроля над какой строкой, это может быть первая строка из каждой группы, как показано выше, так что результат вы получаете:

Date   qtySum  a.weightSum  b.weightSum  barcodeCount 
-------------------------------------------------------------------------- 
2016-01-20  1   1    26    8 
2016-01-21  2   2    26    8 

который я думаю, почему вы в конечном итоге с теми же значениями из подзапроса B повторяется.

Так вот, что касается того, что не так, теперь решение, предполагая, что будут даты в stock_list, которых нет в selected_items, и наоборот, вам нужно полное соединение, но поскольку это не поддерживается в MySQL вы должны использовать UNION, самый простой способ будет:

SELECT t.Date, 
     SUM(t.StockQuantity) AS StockQuantity, 
     SUM(t.StockWeight) AS StockWeight, 
     SUM(t.SelectedWeight) AS SelectedWeight, 
     SUM(t.BarcodeCount) AS BarcodeCount 
FROM ( SELECT date, 
        SUM(qty) AS StockQuantity, 
        SUM(weight) AS StockWeight, 
        0 AS SelectedWeight, 
        0 AS BarcodeCount 
      FROM stock_list 
      GROUP BY Date 
      UNION ALL 
      SELECT date, 
        0 AS StockQuantity, 
        0 AS StockWeight, 
        SUM(weight) AS SelectedWeight, 
        COUNT(BarCode) AS BarcodeCount 
      FROM selected_items 
      GROUP BY Date 
     ) AS t 
GROUP BY t.Date; 

EDIT

Я не могу проверить это, и я не уверен в вашей точной логики, но вы можете использовать variables to calculate a running total in MySQL. Это должно дать представление о том, как это сделать:

SELECT Date, 
     StockQuantity, 
     StockWeight, 
     SelectedWeight, 
     BarcodeCount, 
     (@w := @w + StockWeight - SelectedWeight) AS TotalWeight, 
     (@q := @q + StockQuantity - BarcodeCount) AS TotalQuantity 
FROM ( SELECT t.Date, 
        SUM(t.StockQuantity) AS StockQuantity, 
        SUM(t.StockWeight) AS StockWeight, 
        SUM(t.SelectedWeight) AS SelectedWeight, 
        SUM(t.BarcodeCount) AS BarcodeCount 
      FROM ( SELECT date, 
           SUM(qty) AS StockQuantity, 
           SUM(weight) AS StockWeight, 
           0 AS SelectedWeight, 
           0 AS BarcodeCount 
         FROM stock_list 
         GROUP BY Date 
         UNION ALL 
         SELECT date, 
           0 AS StockQuantity, 
           0 AS StockWeight, 
           SUM(weight) AS SelectedWeight, 
           COUNT(BarCode) AS BarcodeCount 
         FROM selected_items 
         GROUP BY Date 
        ) AS t 
      GROUP BY t.Date 
     ) AS t 
     CROSS JOIN (SELECT @w := 0, @q := 0) AS v 
GROUP BY t.Date; 
+0

предыдущий запрос работал с небольшой проблемой, этого нет. – AndroidNewBee

+0

Можете ли вы уточнить, что «не работает»? Ошибка синтаксиса? Неверные результаты? – GarethD

+0

Извините, что сейчас работает, но с небольшой проблемой, пожалуйста, проверьте эту ссылку http://i.stack.imgur.com/9gunD.png за 20 jan 2016, можете ли вы рассказать мне, почему я получаю две записи там, также вы можете помочь мне добавить общее количество предметов и общий вес за этот день. Большое вам спасибо :) – AndroidNewBee

0

Вы можете использовать join. Однако, если набор дат не является одинаковым в обеих таблицах, тогда вам понадобится full outer join. Но это не доступно в MySQL. Вместо этого:

select date, sum(qtySum), sum(weightsum1), sum(weightsum2), sum(barcodeCount) 
from ((Select date as Date, Sum(qty) as qtySum, Sum(weight) as weightSum1, 
       NULL as weightsum2, NULL as barcodeCount 
     From stock_list 
     Group by date 
     ) union all 
     (Select date, null, null, Sum(weight), Count(barcode) as barcodeCount 
     From selected_items 
     Group by date 
     ) 
    ) t 
Group by date; 

Я не уверен, как ваш желаемый результат соответствует запросу, который вы предоставили. Но это должно объединить и объединить данные из двух таблиц по дате, чтобы вы могли завершить запрос.

+0

Спасибо @GordonLinoff, это сработало, как я могу положить тире вместо NULL, и вы можете помочь мне получить общие предметы и общий вес. Я добавляю свои данные в таблицу. Большое вам спасибо. – AndroidNewBee

+0

@AndroidNewBee. , , Вероятно, вы захотите сделать это в приложении. Черта - это строка, тогда как возвращаемые значения - это числа. Если вы хотите тире, вам нужно быть осторожным, как вы преобразовываете числа в строки. –

0

Вы можете использовать оператор FULL JOIN, чтобы решить вашу задачу, если некоторые даты могут не существовать в обеих таблицах.

Select ISNULL(A.date, B.date) AS date, 
     A.qtySum, 
     A.weightSum, 
     B.weightSum, 
     B.barcodeCount 
From 
    (Select date as Date, 
      Sum(qty) as qtySum, 
      Sum(weight) as weightSum 
    From stock_list 
    Group by date) as A 
FULL JOIN 
(Select date, 
     Sum(weight) as weightSum, 
     Count(barcode) as barcodeCount 
From selected_items 
Group by date) as B ON A.date = B.date 
Смежные вопросы