我有一些查询,其中有几个JOINS从多个表中返回数据
SELECT A.ItemID, A.Title, A.PictureURL as Image, SUM(B.AmountPaid) as revenue, COUNT(*) AS numOrders, B.CheckoutStatus_LastModifiedTime, C.HitCount as today, D.HitCount as yesterday
FROM ebay_activelistings A
LEFT JOIN ebay_orders B ON
A.ItemID = B.ItemID
AND ( (B.CheckoutStatus_LastModifiedTime >= :start_date
AND B.CheckoutStatus_LastModifiedTime < :end_date) OR B.CheckoutStatus_LastModifiedTime IS NULL)
AND (B.CheckoutStatus_Status = 'Complete' OR B.CheckoutStatus_Status IS NULL)
LEFT JOIN ebay_hitswatches C ON A.ItemID = C.ItemID
LEFT JOIN ebay_hitswatches D ON A.ItemID = D.ItemID
WHERE
A.ListingStatus = 'Active'
AND C.Timstamp LIKE :end_date2
AND D.Timstamp LIKE :start_date2
" . (count($listingIds) > 0 ? 'AND A.ItemID IN ('.implode(',', $listingIds).')' : '') . "
GROUP BY A.ItemID
此查询正常工作,只会从&#34; ebay_activelistings&#34;中返回一行。表格如果匹配&#34; ItemID&#34;发现在&#34; ebay_orders&#34;表
但是,无论如何,我都希望返回一行,即使没有匹配的&#34; ItemID&#34;在&#34; ebay_orders&#34;那么&#34; B。&#34;数据可以留空,但我仍然可以获得其他数据。
非常感谢任何帮助,谢谢。
答案 0 :(得分:1)
您已使用LEFT JOIN来保留A中的行,即使他们没有B或C或D中的相应元素。
但是,如果您的WHERE子句中有与B或C或D相关的条件,那么这些行将从您的答案中删除。
将关于B或C或D的条件置于JOIN条件下,将这些条件保留在最终答案中。
简短回答 - 将WHERE条件移入JOIN条件。
SELECT A.ItemID, A.Title, A.PictureURL as Image, SUM(B.AmountPaid) as revenue, COUNT(*) AS numOrders, B.CheckoutStatus_LastModifiedTime, C.HitCount as today, D.HitCount as yesterday
FROM ebay_activelistings A
LEFT JOIN ebay_orders B ON
A.ItemID = B.ItemID
AND ( (B.CheckoutStatus_LastModifiedTime >= :start_date
AND B.CheckoutStatus_LastModifiedTime < :end_date) OR B.CheckoutStatus_LastModifiedTime IS NULL)
AND (B.CheckoutStatus_Status = 'Complete' OR B.CheckoutStatus_Status IS NULL)
LEFT JOIN ebay_hitswatches C ON A.ItemID = C.ItemID AND C.Timstamp LIKE :end_date2
LEFT JOIN ebay_hitswatches D ON A.ItemID = D.ItemID AND D.Timstamp LIKE :start_date2
WHERE
A.ListingStatus = 'Active' $itemClause
GROUP BY A.ItemID
但是...在你的php设置$ itemClause如下 - 这将是空白或将包括数字列表。
$itemClause = count($listingIds) > 0 ? ' AND A.ItemID IN ('.implode(',', $listingIds).')' : '';
答案 1 :(得分:0)
我不确定我是否完全了解您的请求的行为以及您对结果的期望。
在您的情况下,这些条件可能过于严格:
AND C.Timstamp LIKE :end_date2
AND D.Timstamp LIKE :start_date2
也许试试
AND (C.Timstamp IS NULL OR C.Timstamp LIKE :end_date2 )
AND (D.Timstamp IS NULL OR LIKE :start_date2)
答案 2 :(得分:0)
考虑以这种方式工作的外部联接:
如果未找到匹配的行,则生成虚拟行以代替匹配的行。该虚拟行完全由NULL值组成。
当我们到达WHERE子句时,任何需要外连接表中的列为非NULL的条件都将排除生成的虚拟行。这有效地否定了“外在性”#34;连接,使其等效于内连接。
将其与问题中的查询特定相关:WHERE子句中的此条件:
C.Timstamp LIKE :end_date2
要求外连接表Timstamp
中的C
为非NULL。
对于具有C.Timstamp
的NULL值的任何行,此条件的计算结果为NULL。由于条件未评估为TRUE,因此将排除该行。这就是我们观察到的行为的原因。
修复方法是删除C.Timstamp
非NULL的要求。
通常的模式是从WHERE子句中删除条件,并重新定位到连接的ON
子句,例如。
LEFT
JOIN ebay_hitswatches C
ON C.ItemID = A.ItemID
AND C.Timstamp LIKE :end_date2
WHERE ...