2010-02-16 4 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을 선택합니다.

  • 비 유형 항목은 ShoppingCart.Quantity 열을 고려해야합니다

  • 1 = IsDownloadable 있습니다. 우리가 티셔츠 4 개를 주문하면 상자 하나에 UPS 라벨을 부착 할 수 있습니다. 그런 다음 다시 상자 당 2 개를 넣을 수 있습니다. 또는 한 상자에 한 개의 셔츠를 넣은 한 쌍의 청바지를 넣을 수 있습니다 (다시 한 개의 추적 라벨이 있음).

나는 끝없는 JOIN과 함께 쓰레기를 만들어 냈고, 아무 것도 사용할 수없는 곳에 중첩되어있다 (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

와우에 적응 될 : MySQL은, 그것은 뭔가를 줄 것이다. ItemID가 실제로 ProductID이고 해당 LabelID가 TrackingID라고 생각하는 것이 맞습니까? 많은 동의어가 있을지 모르지만, 나는 많은 가능성이 있기 때문에 그것을 알아낼 수 없습니다. 내가 옳다면, 지금 당장 그것을 혼란스럽게하지 않더라도 나중에 그렇게 할 것이기 때문에 가능한 빨리 수정하려고한다고 생각합니다. 그리고 그것은 도대체 우리에게 그렇게 혼란스럽게 만듭니다. 사람들 (그리고 누구든지 당신의 코드를 유지할 것입니다). [지금은 일관된 이름을 사용하도록 질문을 수정하는 것이 어떻습니까?] –

+0

Yikes, 죄송합니다. 내 실제 테이블에는 동의어가 그처럼 돌아 다니지 않습니다. 그것의 고정 지금. +1을 지적했다. –

답변

1

HAVING 절을 사용하여 수행 할 수 있습니다.

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 열이 없습니다. SQL-Server에서 작동하도록 getit하려고했으나 할 수 없었습니다. –

+0

나는 당신의 대답이 올바른 방향으로 나를 인도한다고 생각합니다. 지금해야 할 일은 SUM (s.QuantityShipment) = 0 일 때 s.QuantityShipment = NULL 일 때입니다. "HAVING 1 - NULL"은 거짓입니다. 이 일을하는 가장 좋은 방법은 무엇입니까? –

+0

올바른 방향으로 나를 붙잡 았기 때문에 답을 올바르게 표시했습니다. 실제 답변은 원래 질문에 추가되었습니다. 감사! –

0

TrackingNumber가 Null 인 dbo.Tracking을 쿼리 할 수 ​​있습니까? 그게 당신에게 필요한 정보를 줄까요?

+0

음, TrackingNumber는 결코 null이 될 수 없습니다.품목이 운송되지 않으면 행이 작성되지 않습니다. 또한 주문에 대한 추적 번호가 있다고해서 모든 주문 상품이 배송되었음을 의미하지는 않습니다. –

+0

비트 필드 OrderComplete를 만들 수 있습니까? OrderComplete = 1이면 모든 항목이 배송됨을 의미합니다. 그런 다음 질의는 *를 선택하여 dbo.Orders에서 OrderComplete = 1로 이동하여 모든 품목을 선적 한 모든 주문을 얻습니다. – SidC

+0

나는 그것에 대해 생각했다. 그것은 단지 비 관계형 일처럼 보입니다. 그리고 OrderComplete 플래그를 설정하려면 프로그래밍 레이어에서 주문, 항목, 수량 등을 순환해야합니다. 나는 또한 베스트 프랙티스가 될 수 없다고 생각했다. –