2010-02-16 159 views
0

我一直在试图弄清楚如何查询购物车数据库来查找所有包含有形物品的订单(物品可以下载,因此未发货),这些订单尚未分配到UPS跟踪标签。我一直无法做到。ShoppingCart的复杂SQL查询

相关表如下:

// dbo.Inventory - details about the individual product being sold 
- ProductID int primary - Name nvarchar - IsDownloadable bit - 
| 5      | Awesome Shirt | 0     | 
| 7      | An Audio Track | 1     | 

// dbo.ShoppingCart --("ShopID" groups the items in the cart) 
- CartID int primary - ProductID int - ShopID char (guid) - Quantity int - 
| 2     | 5    | e854a982c9264a72 | 4   | 
| 3     | 7    | e854a982c9264a72 | 1   | 

// dbo.Orders - Order information (shipping address, etc) 
- OrderID int primary - ShopID char(x) - BillingInfoColumns - 
| 13     | e854a982c9264a72 | Name,Address,etc | 

// dbo.Tracking - Shipments' (note: a shipment can contain several items) tracking numbers 
- TrackingID int primary - OrderID int - TrackingNumber char(x) - 
| 5      | 13   | Ze5Whatever...   | 

// dbo.ShippedItems - Maps a ShoppingCart's shipped items to tracking numbers 
- ShippingID int primary - TrackingID int - CartID int - QuantityInShipment int 
| 6      | 5    | 2   | 3      | 

希望上面提供的DB是如何设计的合理近似。

因此,要澄清我我需要:

  • 选择的是还没有发行的所有的有形物品的所有OrderIDs。

  • 非有形物品是IsDownloadable = 1

  • 必须考虑到ShoppingCart.Quantity柱。如果我们订购4件T恤,我们可以将它们放在一个箱子中(带有一个UPS追踪标签)。然后再一次,我们可以把每盒2个。或者我们可以将一件带有一件衬衫的牛仔裤放在同一个盒子里(再次,带有一个跟踪标签)等等。

我一直在编写无尽的JOIN和嵌套的WHERE NOT IN(SELECT * FROM)无效的垃圾。可悲的是,我似乎无法将我的头围绕它......我仍在等待我的灵感时刻。

我是比较新的SQL和数据库设计,所以任何信息或(建设性)的批评将不胜感激。如果您认为这会有所帮助,请随意在数据库本身的设计中打洞。 :-)


// I wish I could run this on my brain right now... 
// (Neurons, apparently, are "excitable") 
UPDATE Brain SET Neuron = 'Excited' WHERE Cortex = 'SQL' 

UPDATE

这里是我想出了感谢伯努瓦Vidis。这是我在真实表格/数据上使用的实际查询:

SELECT 
     d.OrderID 
    FROM 
     Person.ShoppingCart c 
    JOIN 
     Inventory.Item i 
    ON 
     i.ItemID = c.ItemID 
    JOIN 
     Orders.Details d 
    ON 
     d.ShopID = c.ShopID 
    LEFT JOIN 
     Orders.Shipping s 
    ON 
     d.OrderID = s.OrderID 
    LEFT JOIN 
     Orders.ShippedItems si 
    ON 
     s.ShippingID = si.ShippingID 
    WHERE 
     i.DownloadableMedia = 0 AND 
     d.Billed = 1 AND 
     d.Ordered = 1 
    GROUP BY 
     d.OrderID 
    HAVING 
     SUM(c.Quantity) > CASE WHEN SUM(si.Quantity) IS NULL THEN 0 ELSE SUM(si.Quantity) END 
+1

哇。我是否认为ItemID实际上是一个ProductID,并且该LabelID是一个TrackingID?甚至可能会有更多的同义词,但我无法弄清楚,因为有这么多的可能性。如果我是对的,我认为你想尽快解决这个问题,因为即使它现在不会让你感到困惑,它会在以后。它肯定会让我们对所有人(以及将维护你的代码的人)感到困惑。 [如何更新问题以使用一致的命名?] – 2010-02-16 17:24:39

+0

Yikes,对不起。我的实际表格没有像这样飞行的同义词。现在它是固定的。 +1指出。 – 2010-02-16 17:35:44

回答

1

您可能可以使用HAVING子句执行此操作。在MySQL中,它会看到这样的:

SELECT 
    c.OrderID, 
    SUM(c.Quantity) AS tangible_products_number, 
    SUM(s.QuantityInShipment) as shipped_items_number 
FROM 
( 
    Inventory i, 
    ShoppingCart c 
) 
LEFT JOIN 
    ShippedItems s 
ON 
    c.OrderID = s.OrderID 
WHERE 
    i.ProductID = c.ItemID AND 
    i.IsDOwnloadable = 0 AND 
    c.OrderID = t.OrderID AND 
    s.CartID = c.ID 
GROUP BY 
    c.OrderID 
HAVING 
    SUM(c.Quantity) > SUM(s.QuantityInShipment) 

通过语法集团将可能需要适应于SQL-服务器

+0

感谢您的反馈。 ShoppingCart表没有OrderID列。我试图getit在SQL-Server中工作,但无法执行。 – 2010-02-16 17:48:15

+0

我认为你的回答是引导我走向正确的方向。我现在需要做的是使SUM(s.QuantityShipment)= 0当s.QuantityShipment = NULL。 “HAVING 1 - NULL”是错误的。什么是最好的方法来做到这一点? – 2010-02-16 18:04:53

+0

我标记你的答案是正确的,因为它让我朝着正确的方向前进。实际的答案已附加到我原来的问题。谢谢! – 2010-02-16 18:29:51

0

你能查询dbo.Tracking哪里的TrackingNumber是空的吗?这会给你所需的信息吗?

+0

那么,TrackingNumber永远不会为空。该行不会创建,除非物品已发货。另外,仅仅因为我们有订单的追踪号码并不意味着所有订单的商品都已发货。 – 2010-02-16 17:16:51

+0

是否可以创建一个位域OrderComplete?如果OrderComplete = 1表示所有物品已发货。然后,您的查询将是select * from dbo.Orders,其中OrderComplete = 1以获取所有已交付所有商品的订单。 – SidC 2010-02-16 17:32:54

+0

我想过那个。这看起来像是一个非关系的事情。要设置OrderComplete标志,我必须在编程层次中循环订单,项目,数量等。我也认为这不可能是最佳做法。 – 2010-02-16 17:39:16