2015-08-22 4 views
0

У меня есть запрос с объединениями и подзапросом (производная таблица). Если я запустил его без LIMIT 1, результат будет содержать поле vat и id с соответствующими значениями.mysql left join subquery with limit дает поля с нулевыми значениями для родительского select

Первый запрос:

SELECT i.id, i.vat, pl.invoice_id as inv_id, pl.product_id as pl_id, pl.quantity as qty, pl.price, pl.currency, p.name, p.manufacturer, p.list_price, p.cost_price, p.wholesale_price, p.cikkszam, p.unit, p.group_name 
FROM soulnsoda_products_log pl 
LEFT JOIN soulnsoda_products p ON pl.product_id=p.id 
LEFT JOIN (select id, vat, parent_id, beneficiary_account from soulnsoda_invoices) as i ON i.parent_id>0 AND pl.invoice_id=i.parent_id AND pl.product_id=i.beneficiary_account 
WHERE pl.action=6 AND p.cikkszam = 'S6511415-BLK' AND (pl.stamp BETWEEN '2015-08-15 00:00:00' AND '2015-08-15 23:59:59') AND pl.warehouse_name='Garage - Árkád' 
ORDER BY p.cikkszam 

Результат будет содержать i.id и i.vat поля со значениями, но дублирующие строки:

id  vat  inv_id pl_id qty  price  name     
93119 27.00 93117 21961 -1.00 1096.85 HUF SUPRA ICON SX BLACK DB 
93120 27.00 93117 21961 -1.00 1096.85 HUF SUPRA ICON SX BLACK DB 
93119 27.00 93117 21961 -1.00 1096.85 HUF SUPRA ICON SX BLACK DB 
93120 27.00 93117 21961 -1.00 1096.85 HUF SUPRA ICON SX BLACK DB 

я должен отфильтровать строки с дублируется идентификаторы. Когда я использую LIMIT 1, дублирование исчезнет, ​​но поле id и vat будет NULL. И я не знаю, почему ...

Второй запрос с LIMIT:

SELECT i.id, i.vat, pl.invoice_id as inv_id, pl.product_id as pl_id, pl.quantity as qty, pl.price, pl.currency, p.name, p.manufacturer, p.list_price, p.cost_price, p.wholesale_price, p.cikkszam, p.unit, p.group_name 
FROM soulnsoda_products_log pl 
LEFT JOIN soulnsoda_products p ON pl.product_id=p.id 
LEFT JOIN (select id, vat, parent_id, beneficiary_account from soulnsoda_invoices LIMIT 1) as i ON i.parent_id>0 AND pl.invoice_id=i.parent_id AND pl.product_id=i.beneficiary_account 
WHERE pl.action=6 AND p.cikkszam = 'S6511415-BLK' AND (pl.stamp BETWEEN '2015-08-15 00:00:00' AND '2015-08-15 23:59:59') AND pl.warehouse_name='Garage - Árkád' 
ORDER BY p.cikkszam 

Результат будет две строки, которые в порядке, но нет идентификатор и чан:

id  vat  inv_id pl_id qty  price  name     
NULL NULL 93117 21961 -1.00 1096.85 HUF SUPRA ICON SX BLACK DB 
NULL NULL 93117 21961 -1.00 1096.85 HUF SUPRA ICON SX BLACK DB 

Я пробовал LIMIT 1, GROUP BY, MIN, MAX и т. Д.

Я знаю, что DISTINCT работает с моим образцом, но это упрощенный запрос, чтобы показать вам проблему.

Как добиться результата только двумя строками, но со значением в столбце id и vat, используя некоторую технику в (или около) подзапросе LEFT JOIN?

+0

нуль находится на правом столе, а не на левом. поэтому используйте 'is null 'или' is not null' – Drew

+0

Спасибо, но нулевой результат, к сожалению. Поэтому я не мог с этим справиться. – Tamas

ответ

0

Если ваша проблема заключается в дублировании строк, используйте select distinct. На самом деле, было бы лучше, чтобы найти причину дублирования, но это может быть то, что вы хотите:

SELECT distinct i.id, i.vat, pl.invoice_id as inv_id, pl.product_id as pl_id, 
     pl.quantity as qty, pl.price, pl.currency, p.name, p.manufacturer, 
     p.list_price, p.cost_price, p.wholesale_price, p.cikkszam, p.unit, p.group_name 
FROM soulnsoda_products_log pl LEFT JOIN 
    soulnsoda_products p 
    ON pl.product_id = p.id LEFT JOIN 
    soulnsoda_invoices i 
    ON i.parent_id > 0 AND pl.invoice_id = i.parent_id AND 
     pl.product_id = i.beneficiary_account 
WHERE pl.action = 6 AND 
     p.cikkszam = 'S6511415-BLK' AND 
     pl.stamp >= '2015-08-15' AND pl.stamp < '2015-08-16' AND  
     pl.warehouse_name = 'Garage - Árkád' 
ORDER BY p.cikkszam 

Некоторые примечания:

  • left join на p это превращается в внутреннее соединение по пункт where.
  • Подзапрос не нужен и, по сути, просто вредит производительности.
  • Эта версия упрощает сравнение дат.
+0

Я пробовал выделить в этом смысле, но, как я пытаюсь объяснить, мне приходится иметь дело с подзапросом, так как это упрощенная версия, чтобы понять мою проблему. В текущем запросе есть несколько SUM в родительском SELECT. Поэтому важно иметь дело только с двумя строками во внутреннем выборе. Но спасибо за ваши усилия! – Tamas

0

В вашем первом запросе статья WHERE ... p.cikkszam = 'S6511415-BLK' преобразует вашу первую ЛЕВУЮ ПРИСОЕДИНЕНИЕ в обычный внутренний JOIN.

ORDER BY p.cikkszam пункт ничего не делает в сочетании с WHERE ... p.cikkszam = 'S6511415-BLK': в этом столбце вашего результирующего набора есть только одно значение.

Ваша временная совместимость с временной меткой немного неуклюжая и почти правильная. Попробуйте это, и это будет идеально.

  pl.stamp >= '2015-08-15' 
    AND pl.stamp < '2015-08-15' + INTERVAL 1 DAY 

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

select id, vat, parent_id, beneficiary_account from soulnsoda_invoices LIMIT 1 

Это выбирает «первый» ряд счетов-фактур Таблица.Беда в том, что без ORDER BY MySQL и другие двигатели RDMS не имеют твердого понятия «первый». Таким образом, ваш второй запрос неверен.

Ваш запрос, кажется, запрашивает одну строку для счета за конкретный продукт ('S6511415-BLK') отправлен (action=6) с определенного склада в определенный день. В вашей таблице счетов есть две соответствующие строки. В другой таблице также есть две соответствующие строки. Или, может быть, в таблице счетов-фактур есть четыре совпадающих строки.

Вы не указали нам содержимое своих таблиц. Поэтому нам сложно помочь вам разобраться, где находятся ваши повторяющиеся строки. Вы можете использовать SELECT DISTINCT для исключения дубликатов в таблице счетов-фактур, например, если хотите.

Вот запрос, который я предлагаю. Это даст вам результат с двумя строками.

SELECT i.id, i.vat, 
     pl.invoice_id as inv_id, pl.product_id as pl_id, pl.quantity as qty, 
     pl.price, pl.currency, 
     p.name, p.manufacturer, p.list_price, p.cost_price, 
     p.wholesale_price, p.cikkszam, p.unit, p.group_name 
    FROM soulnsoda_products_log pl 
    JOIN soulnsoda_products p ON pl.product_id=p.id 
    LEFT JOIN (SELECT DISTINCT id, vat, 
          parent_id, beneficiary_account 
         FROM soulnsoda_invoices 
      ) as i ON i.parent_id > 0 
        AND pl.invoice_id = i.parent_id 
        AND pl.product_id = i.beneficiary_account  
WHERE pl.action=6 
    AND p.cikkszam = 'S6511415-BLK' 
    AND pl.stamp >= '2015-08-15' 
    AND pl.stamp < '2015-08-15' + INTERVAL 1 DAY 
    AND pl.warehouse_name='Garage - Árkád' 
ORDER BY p.cikkszam, i.id 
+0

Спасибо Олли. Я знаю, что трудно понять правильный путь, поскольку структура не была объяснена. Если я запустил ваш выбор, я получил 4 строки. Основная проблема заключается в том, что в счете есть два элемента в разных строках. Таким образом, invoice_id - это то же самое, product_id - то же самое, только идентификатор строки счета-фактуры (это сам идентификатор в таблице invoces) отличается. В этом случае, когда я присоединился к счетам и таблице products_log с invoiced_id и paroduct_id, у меня есть четыре строки. Поскольку есть два совпадающих строки, которые будут дублироваться ... – Tamas

 Смежные вопросы

  • Нет связанных вопросов^_^