2009-08-18 4 views
0

또 다른 SQL 문제로 현재 문제가 있습니다. 이 사실을 제대로 알기 위해서는 약간의 시간을 할애해야합니다.고유 한 외래 키가있는 쿼리에서 행을 선택 하시겠습니까?

어쨌든 누군가 다른 사람이 쓴이 쿼리는 몇 가지 테이블에서 값을 가져옵니다.

이제 두 개 이상의 항목이 동일한 ProductID를 가질 수 있습니다. 따라서 동일한 ProductID를 가진 모든 항목이 3 개 반환 될 수 있지만 설명이 다릅니다.

ProductID 당 하나의 항목 만 선택하고 싶습니다. 나는 DISTINCT를 사용하여 그룹화했지만 많은 오류가 발생합니다. 또한 이것은 ACCESS 데이터베이스를위한 것입니다.

내 그룹화를 엉망으로 만드는 선택 쿼리에 사용 된 논리 때문이라고 생각합니다. 여기

쿼리입니다 (나는 그것을 좀 더 나은 서식을 시도하는 온라인 도구 있지만 여전히 큰 혼란을 사용했다)

SELECT tblproducts.productid, 
    tblproducts.categorycode, 
    tblproducts.scaletitle, 
    tblproducts.picture, 
    tblitems.cost, 
    tblitems.modelnumber, 
    tblitems.itemid, 
    Iif([tblitems]![tradeapproved],Iif(([tblitems]![markup]/100) <> 0,(Iif(([tblitems]![supplierdiscount]/100) <> 0, 
                       [tblitems]![cost] - ([tblitems]![cost] * ([tblitems]![supplierdiscount]/100)), 
                       [tblitems]![cost])) * ([tblitems]![markup]/100), 
             0) + Iif(([tblitems]![supplierdiscount]/100) <> 0, 
               [tblitems]![cost] - ([tblitems]![cost] * ([tblitems]![supplierdiscount]/100)), 
               [tblitems]![cost]) + [tblitems]![tradeapprovedcost] + [tblitems]![shippingcost], 
     Iif(([tblitems]![markup]/100) <> 0,(Iif(([tblitems]![supplierdiscount]/100) <> 0, 
                [tblitems]![cost] - ([tblitems]![cost] * ([tblitems]![supplierdiscount]/100)), 
                [tblitems]![cost])) * ([tblitems]![markup]/100), 
      0) + Iif(([tblitems]![supplierdiscount]/100) <> 0, 
         [tblitems]![cost] - ([tblitems]![cost] * ([tblitems]![supplierdiscount]/100)), 
         [tblitems]![cost]) + [tblitems]![shippingcost]) AS price 
FROM  (tblitems 
     INNER JOIN tblproducts 
     ON tblitems.productid = tblproducts.productid) 
    INNER JOIN tblsuppliers 
     ON tblproducts.supplierid = tblsuppliers.supplierid 
WHERE tblproducts.categorycode = 'BS' 
    AND tblitems.tradeapproved = 0 
    AND tblsuppliers.active = on 
    AND tblitems.isaccessory = false 
ORDER BY Iif([tblitems]![tradeapproved],Iif(([tblitems]![markup]/100) <> 0,(Iif(([tblitems]![supplierdiscount]/100) <> 0, 
                       [tblitems]![cost] - ([tblitems]![cost] * ([tblitems]![supplierdiscount]/100)), 
                       [tblitems]![cost])) * ([tblitems]![markup]/100), 
             0) + Iif(([tblitems]![supplierdiscount]/100) <> 0, 
               [tblitems]![cost] - ([tblitems]![cost] * ([tblitems]![supplierdiscount]/100)), 
               [tblitems]![cost]) + [tblitems]![tradeapprovedcost] + [tblitems]![shippingcost], 
     Iif(([tblitems]![markup]/100) <> 0,(Iif(([tblitems]![supplierdiscount]/100) <> 0, 
                [tblitems]![cost] - ([tblitems]![cost] * ([tblitems]![supplierdiscount]/100)), 
                [tblitems]![cost])) * ([tblitems]![markup]/100), 
      0) + Iif(([tblitems]![supplierdiscount]/100) <> 0, 
         [tblitems]![cost] - ([tblitems]![cost] * ([tblitems]![supplierdiscount]/100)), 
         [tblitems]![cost]) + [tblitems]![shippingcost]) 

는 사람이 대한 빠른 수정을 게시 할 수 있습니까? 감사합니다

+2

코드는 피 묻은 미로입니다. 나는 형식화를 시도했지만 저녁까지 인내심을 잃어 버렸다. 그것을 읽을 수있는 형식으로 포맷 해 주시겠습니까? 아니면 단순화 된 버전을 올리시겠습니까? – Eric

+0

@ Eric, 여기 같은 이야기가 ... 포맷을 시도했지만 포기했습니다. –

+0

좋아, 나는 그것이 거대하다는 것을 안다, 게다가 내가 준 코드는 이것을 12 번처럼 가지고있다! 함께 일하는 것은 악몽입니다. ​​나는 편집을하고 더 나은 것을 게시 할 것입니다. – ddd

답변

1

글쎄, 당신은 당신이 물건을 배우고 싶어했다 이후 :

내부 이 제품 일련의 항목을 연결하지만 전체 세트됩니다 조인. 각 결과 이상

select ItemId from Item_tbl 

그리고 루프, 하나의 제품 ID를 얻기 : 당신이 3 ProductIds 1 개 항목이있는 경우 그래서 당신이

ProdId ItemId Description 
1  1  Handy Dandy Randy Sandy! 
2  1  Easily Accessible personal grooming comb. 
3  1  This item provides a man or woman with extra re... 

를 얻을 것이다 것은 그래서 당신이 정말로 무엇을 원하는 모든 ItemIds를 얻을 수있다 항목 별 :

이제 SQL을 사용하여 루프를 제안하는 사람은 소리를 지르고, (보통) 올바르게 적용됩니다. 그러나 이것은 사람들이 보통하는 일이 아니기 때문에 어려운 질문입니다.

그룹별로 올바른 행을 잡았습니다. Group By는 "구분 된 열 X가있는 모든 행을 통합"하여 열 X가 ItemId가되는 위치를 말합니다. 그래서 : ItemId 당 하나의 행을주세요.

이제 항목 Id 1.이 임의에서 제품 ID를 선택하지만, 특정 집계 함수에 맞는 오히려 제품 일련없는 수행하는 사기꾼 방법을 그 3 개 제품에서 제품 ID를 선택 에 있습니다. 가장 일반적인 것은 최소 및 최대입니다.

select 
    ItemId, 
    max(ProductId) 
from Itemtbl i 
inner join Producttbl p 
    on i.itemid = p.itemId 
group by ItemId 

이렇게하면 각 ItemId에 대해 가장 큰 ProductId가 생성됩니다. 동일한 작업을 수행하여 최소값을 얻을 수 있습니다.

이제 까다로운 것은 가장 최근에 업데이트 된 것과 같은 조건에 맞는 ProductId를 찾는 것입니다. 당신이 말하고자하는 것은 "ItemId를 선택하고 max (updatedDate)를 선택한 다음 이 최대 업데이트 날짜의 ProductId를과 함께 가져 오지만 SQL에서는 작동하지 않습니다.최대 PRODUCTID 반드시 최대 updatedDate있는 행에서 오지 않기 때문에

select 
    ItemId, 
    max(ProductId), 
    max(updatdedDate) 
from Itemtbl i 
inner join Producttbl p 
    on i.itemid = p.itemId 
group by ItemId 

:

이 쿼리는 잘못된 결과를 제공 할 것입니다.

대신이 수행하는 쿼리를 작성해야한다 :

  1. 이 항목 ID를 선택합니다 (예 : 5), 그리고 maxUpdated 날짜 (예 : 2005년 5월 5일)
  2. 가 Products_tbl로 돌아가과 ItemId가 5이고 updatedDate가 2005/5/5 인 ProductId를 찾습니다.

해당 쿼리는 연습으로 남아 있습니다. (하지만 버그가 있습니다! 두 제품의 마지막 업데이트 날짜가 동일하고 ItemId가 동일한 경우는 어떻게 되나요?

+0

나는 당신의 대답과 노력을 좋아합니다. 그러나 그것은 지금 정말로 나를 도왔습니다. 나는 SQL의 기초를 알고 있지만이 쿼리는 작업 할 수있는 악몽 일 뿐이며 많은 에러가 발생하더라도 if 문과 관련이 있다고 생각한다. VS2008 쿼리를 구문 분석 할 수 없습니다! 다시 한번 감사드립니다 – ddd

+0

원본 쿼리를 파생 테이블로 래핑하고 특정 속성을 선택했습니다. itemId에 max를하려고 할 때 productId에 대한 집계 함수가 없다는 오류가 발생합니다. – ddd

+0

productId에 대한 집계 함수가 없습니다. 당신은 "group by"절이 없으므로 max를 사용할 수 없습니다. 솔직히이 문제를 해결하는 가장 좋은 방법은 문제를 해결하는 것입니다. 어떤 테이블을 가지고 있는지, 어떤 PKs와 FK를 가지고 있는지, 그리고 무엇을 얻으려고하는지 파악하십시오. 그것이 그대로, 스파게티 (심지어 다시 포맷)처럼 보입니다. –

1

가독성을 높이기위한 첫 번째 단계는 Price에 대한 멋진 논리를 포함하는 tblItem에 대한보기를 만드는 것입니다. :

보기 [vwItemsWithAdjustedCost]

SELECT 
    ProductID, 
    TradeApproved, 
    IsAccessory, 
    Cost, 
    ModelNumber, 
    ItemID, 
    IIf(
     (SupplierDiscount/100) <> 0, 
     Cost - (Cost * (SupplierDiscount/100)), 
     Cost 
    ) AS AdjustedCost 
FROM tblItems   

보기 [vwItemsWithPrice]

SELECT 
    ProductID, 
    TradeApproved, 
    IsAccessory, 
    Cost, 
    ModelNumber, 
    ItemID, 
    IIf(
     (Markup/100) <> 0, 
     AdjustedCost * (Markup/100), 
     0 
    ) 
    + AdjustedCost 
    IIf(
     TradeApproved, 
     TradeApprovedCost, 
     0 
    ) 
    + ShippingCost AS Price 
FROM vwItemsWithAdjustedCost 
다음

같은 제품 ID와 일치하는 항목 중 하나를 선택하는 기준이 무엇인지 결정해야합니다. 3 개의 항목은 표시하려는 ID가 동일합니다.

이 각 제품 ID에 대해 말한다
SELECT 
    P.ProductID, 
    P.CategoryCode, 
    P.ScaleTitle, 
    P.Picture, 
    IP.Cost, 
    IP.ModelNumber, 
    IP.ItemID, 
    IP.Price 
FROM 
    tblProducts P 
    INNER JOIN (
     SELECT 
      ProductID, 
      MIN(ItemID) AS MinItemID 
     FROM tblItems I 
     GROUP BY ProductID 
    ) S 
     ON S.ProductID = P.ProductID 
    INNER JOIN vwItemsWithPrice IP 
     ON IP.ItemID = S.MinItemID 
WHERE 
    P.CategoryCode = 'BS' 
    AND IP.TradeApproved = 0 
    AND IP.IsAccessory = false 
ORDER BY IP.Price 

이 나있는 최초 (하단)의 항목 ID를 제공 : 톰에 의해 언급 한 바와 같이

는 쉬운 방법은,이 같은 일치하는 최초 (하단)의 ID를 얻는 것입니다 tblItems에서 내보기로 그 조인을 사용합니다.

희망이 도움이됩니다.

+0

답변 해 주셔서 감사합니다. 나는 당신의 방법을 시도했지만 여전히 조금 붙어 있습니다. 나는 당신의 마지막 스 니펫을 가지고 있지만 어디서나 주문하지 않고 간단하게 *를 선택합니다. 뷰에서 최종 내부 조인을 가리키는 액세스 구문 오류가 발생합니다.나는 문제가되지는 않지만 여전히 같은 오류가 있음을 알기 때문에 항목 테이블에 대한보기를 대체하려고했습니다. – ddd

+0

오류가없는 구문 오류 연산자 및 ON 코드 S 를 도시 S.ProductID = P.ProductID 이너 (tblItems에서 항목 ID를 선택) 가입 IP ON IP.ItemID = S.MinItemID를 액세스를 사용하는 – ddd

+0

및 나는 조인을 중첩해야한다고 생각한다. (잘못 사용했을 수 있기 때문에 잠시있다.) FROM (tblProducts P ... ON S.ProductID = P.ProductID) INNER JOIN. . –

관련 문제