2012-06-21 3 views
1

У меня есть один запрос, который я использую, чтобы суммировать общие итоги и показывать последнюю дату для каждого элемента запаса. У меня есть два разных типа запасов 0 и 1 (входящий, исходящий). Я хочу быть в состоянии положить внизу страницы «Последний полученный товар был по адресу:» & «Последняя партия была у:».Объединить три (сложных) запроса

Вот что у меня есть для моего основного запроса к группе и просуммировать инвентарь:

$query = "Select * 
      FROM (SELECT id, type, color, product, 
         SUM(Quantity) AS TotalQuantity, MAX(Date) AS LatestDate 
       FROM inventory 
       GROUP BY id, color, type) AS alias 
      WHERE TotalQuantity > 0"; 

Теперь я хочу, чтобы иметь возможность также запустить эти два запроса, чтобы захватить последний раз обновленное для «акций» 0 и 1 (Входящие, исходящие)

$query = "SELECT MAX(Date) FROM inventory WHERE stock = 0"; 

$query = "SELECT MAX(Date) FROM inventory WHERE stock = 1"; 

Любая помощь в сочетании этих трех запросов? Я пытался UNION, но не имел большой удачи.

+0

Извините, что сложного в 'SELECT MAX (Date) FROM inventory WHERE stock = 0'? – Seph

+0

@Seph первые осложнили;) если бы это было три SELECT MAX (Date), я мог бы, вероятно, понять это. – cantaffordretail

ответ

3

попробовать что-то вроде этого:

SELECT alias.*, 
    zeroStock.zeroDate, 
    nonzeroStock.nonzeroDate 
FROM 
    (
     SELECT id, 
      type, 
      color, 
      product, 
      SUM(Quantity) AS TotalQuantity, 
      MAX(Date) AS LatestDate 
     FROM inventory 
     GROUP BY id, color, type 
    ) alias INNER JOIN 
    (
     SELECT id, MAX(Date) zeroDate 
     FROM inventory 
     WHERE stock = 0 
     GROUP BY id 
    ) zeroStock on alias.id = zeroStock.id 
    INNER JOIN 
    (
     SELECT id, MAX(Date) nonzeroDate 
     FROM inventory 
     WHERE stock = 1 
     GROUP BY id 
    ) nonzeroStock on alias.id = nonzeroStock.id 
WHERE alias.TotalQuantity > 0 
1

Вы можете использовать CROSS JOIN добавить даты для каждой строки обычного оператора выбора.

SELECT * 
FROM (
      SELECT * 
      FROM (
        SELECT id, type, color, product, SUM(Quantity) AS TotalQuantity, MAX(Date) AS LatestDate 
        FROM inventory 
        GROUP BY 
          id, color, type 
       ) AS alias 
      WHERE TotalQuantity > 0 
     ) AS q 
     CROSS JOIN (SELECT MAX(Date) AS MaxIncoming FROM Inventory WHERE stock = 0) AS r 
     CROSS JOIN (SELECT MAX(Date) AS MaxOutgoing FROM Inventory WHERE stock = 1) AS s 

Mysql Cross Join

Cross Join is also called Cartesian Product Join. The Cross Join in SQL return you a result table in which each row from the first table is combined with each rows from the second table

Редактировать

для записи, вы можете упростить формулировку, используя пункт HAVING вместо пункта о вашем TotalQuantity WHERE.

SELECT * 
FROM (
      SELECT id, type, color, product, SUM(Quantity) AS TotalQuantity, MAX(Date) AS LatestDate 
      FROM inventory 
      GROUP BY 
        id, color, type 
      HAVING 
        SUM(Quantity) > 0   
     ) AS q 
     CROSS JOIN (SELECT MAX(Date) AS MaxIncoming FROM Inventory WHERE stock = 0) AS r 
     CROSS JOIN (SELECT MAX(Date) AS MaxOutgoing FROM Inventory WHERE stock = 1) AS s   
+0

Выглядит многообещающе, но я получаю сообщение об ошибке: ... для использования рядом с 'SELECT MAX (Date) AS MaxOutgoing FROM inventory WHERE stock = 1) AS r' – cantaffordretail

+0

@mcflause - My bad. Я изменил это заявление. Вы можете проверить это? –

2

Попробуйте один

Select 
    alias.id, 
    alias.type, 
    alias.color, 
    alias.product, 
    Stock0.S0, 
    Stock1.S1 
FROM (SELECT 
     id, 
     type, 
     color, 
     product, 
     SUM(Quantity) AS TotalQuantity, 
     MAX(Date)  AS LatestDate 
     FROM inventory 
     GROUP BY id, color, type) AS alias 
    left join (SELECT 
       id, 
       MAX(Date)   S0 
      FROM inventory 
      WHERE stock = 0) as Stock0 
    on Stock0.id = alias.id 
    left join (SELECT 
       id, 
       MAX(Date)   S1 
      FROM inventory 
      WHERE stock = 0) as Stock1 
    on Stock1.id = alias.id 
WHERE TotalQuantity > 0 
+0

Вы проверили запрос ??? –

0
SELECT id, type, color, product, 
        SUM(Quantity) AS TotalQuantity, MAX(Date) AS LatestDate, null AS stock 
      FROM inventory 
      GROUP BY id, color, type 
HAVING TotalQuantity > 0 

UNION ALL 

SELECT null, null, null, null, null, MAX(Date), stock 
FROM inventory WHERE stock IN (0,1) GROUP BY stock 
0

Ты лучше работает опрашивает 2 и 3 отдельно от запроса 1. Запросы 2 и 3 имеют отдельную озабоченность из запроса 1, потому что вы намереваясь получить индивидуальные значения в отличие от многоколоночного списка. Кроме того, вы фильтруете результаты в запросе 1, но не в 2 и 3.

Конечно, вы можете CROSS JOIN дважды в подзапросах, но тогда вы будете передавать гораздо больше ненужных данных между вашей БД и приложением. Вам нужно только получить два значения , а не два целых столбцов (что я могу добавить, не имеют отношения к остальной части набора результатов, что еще больше подчеркивает его неэлегантность).

Кроме того, CROSS JOIN подход предполагает, что будет по крайней мере, одну строку, удовлетворяющую условию SUM(Quantity) > 0. Что, если никто из них не удовлетворит? ... Тогда у вас также не будет ваших последних дат выпуска/выхода! Хотя, возможно, маловероятно, этот случай использования должен быть принят во внимание.

Сказав это, вы можете переписать свой первый запрос, с тем, чтобы избежать подзапрос:

SELECT 
    id, 
    color, 
    type, 
    product, 
    SUM(Quantity) AS TotalQuantity, 
    MAX(Date) AS LatestDate 
FROM 
    inventory 
GROUP BY 
    id, 
    color, 
    type 
HAVING 
    SUM(Quantity) > 0 

Вы можете объединить запросы 2 и 3 с помощью условных проверок в агрегатной функции MAX():

SELECT 
    MAX(CASE WHEN stock = 0 THEN Date ELSE NULL END) AS s0_maxdate, 
    MAX(CASE WHEN stock = 1 THEN Date ELSE NULL END) AS s1_maxdate 
FROM 
    inventory