0

我有一个带有连接和子查询(派生表)的查询。如果我在没有 LIMIT 1 的情况下运行它,结果将包含具有正确值的 vat 和 id 字段。

第一个查询:

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  

我必须过滤掉具有重复 ID 的行。当我使用 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:

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 正在处理我的示例,但它是一个简化的查询,可以向您展示问题本身。

如何使用 LEFT JOIN 子查询中(或周围)的某种技术,仅使用两行但在 id 和 vat 列中有一个值来实现结果?

4

2 回答 2

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 joinon被子句p变成了内部连接。where
  • 子查询不是必需的,实际上只会损害性能。
  • 此版本简化了日期比较。
于 2015-08-22T12:57:09.353 回答
0

在您的第一个查询中,该子句WHERE ... p.cikkszam = 'S6511415-BLK'将您的第一个 LEFT JOIN 转换为普通的内部 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 BYMySQL 和其他 RDMS 引擎,就没有“第一”的可靠概念。所以你的第二个查询不正确。

您的查询似乎要求在某一天从某个仓库'S6511415-BLK'发货( )的特定产品( )每张发票有一行。action=6您的数据中的 invoices 表中有两个匹配的行。在其他一些表中也有两个匹配的行。或者您的发票表中可能有四个匹配的行。

你没有向我们描述你的表格的内容。因此,我们很难帮助您找出重复行的位置。如果您愿意,可以使用 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
于 2015-08-22T13:27:46.703 回答