2010-07-26 3 views
0

비슷한 스레드가 시작되었지만 문제가 더 어려워서 처음부터 다시 시작하겠습니다.
DB에 10 개의 인벤토리 슬롯이 있다고 상상해보십시오 (사용자 행의 열). 사용자가 항목을 선택하면 첫 번째 빈 열에 배치해야합니다 (업데이트 됨). 그러나 만약 내가 유연한 디자인을 원한다면 쿼리에서 IF EXISTS를 제외하고 칼럼을 반복하는 방법은 무엇입니까? 항목의 순서대로 행에 항목을 넣으면 (각 항목은 특정 슬롯에 속함) 잘 처리 할 수 ​​없습니다. 사용자가 1 번 슬롯과 3 번 슬롯이 가득 차면 다음 선택 항목이 2 번 슬롯에 들어가야합니다. 희망, 그 더 명확 지금, 감사합니다!SQL - 열을 통해 루핑, 비어있는 것을 발견하면 업데이트하십시오.

+1

주문이 중요한 경우 행에 "Slot"열을 추가하여 해당 순서를 나타냅니다. –

+0

@dcp와 @Chris가 아래에서 말하는 것을 들어보십시오. 당신의 스키마는 엉성 해져서 계속 진행하기 전에 수정해야합니다. –

답변

1

인벤토리 아이템에 대한 다른 테이블을 가지고 있지 않은 이유는 무엇입니까? 그래서 지금

---------- 
inventory 
---------- 
id int 
description varchar(100) 

--------------- 
inventory_item 
--------------- 
id int 
inventory_id int (foreign key to inventory table) 
sequence_num int (indicates which "slot" the data represents) 

, 당신은 재고의 행을 가질 수있다, 당신은 값을 얻을로 당신은 inventory_item에 행을 삽입 할 수 : 그래서 당신은 다음과 같이 재고 테이블과 inventory_item 테이블이있을 것이다. 따라서 값이 3 개인 경우 inventory_item에 3 개의 행을 삽입하면됩니다. 그들이 어떤 "슬롯"에 들어가는 지에 관해서는 sequence_num 필드가이를 알려줄 것입니다.


당신은 같은 것을 할 수있는, 다음으로 사용 가능한 슬롯 번호를 알아 inventory_items 기존 쿼리 편집 : 더 inventory_items 기존 항목이있는 경우,이 1을 반환없는 경우

SELECT coalesce(MAX(sequence_num),0) + 1 next_sequence_num 
    FROM inventory_item 
WHERE inventory_id = xxx 

을, 다음 번 "슬롯 번호"를 사용할 것입니다 (나는 sequence_number라고 부르지 만 똑같은 것).

+0

새 항목을 가져 왔을 때, 그것이 속한 "슬롯"을 어떻게 알 수 있습니까? (첫 번째 비어 있습니다) – Thomas

+0

@ 토마스 - 답변에 대한 최신 편집을 참조하십시오. – dcp

+0

감사합니다. 재고가 필요합니까? 내 말은, 간단한 "사용자"와 각 사용자에게 할당 된 사용자 ID (소유자라고 말하기) – Thomas

1

이렇게하면 1NF가 깨지기 때문에이 문제가 발생합니다.

행에 항목이 있으면 해결할 수 있다고 생각합니다. 각 테이블을 다른 테이블의 한 행에 넣고 그 테이블의 다른 열을 사용하여 순서를 지정할 수 있습니다.

예제에서 Inventoryslot과 관련이있는 것은 확실하지 않지만 테이블은 이와 비슷하게 보입니다.

InventorySlots(InventorySlotId, RelatedFieldID, OrderNumber, ItemID) 

RelatedFieldID 및 OrderNumber에 UNIQUE 색인을 넣으면 동일한 슬롯에있는 두 항목을 방지 할 수 있습니다.

0

이 여전히 행을 사용할 수 있습니다. 그냥 열 "SlotOrder"또는 somesuch를 추가하십시오. (: 사이비 코드 - 전혀 테스트 경고) : 그런 다음 쿼리는 같은 간다

declare @Slot int 
set @Slot = 1 
if @Slot <= (Select Max(SlotOrder) from Inventory) 
    select @Slot = (Select Max(SlotOrder) + 1 from Inventory) 
if @Slot >= 10 
    Insert Into Inventory(Item, SlotOrder) 
    Values(@Item, @Slot) 
Else -- Tell the user the inventory is full 
0

테이블의 항목은 특별한 순서가 없다, 그래서 혼자 순서가 다른 슬롯을 구별하는 데 사용할 수 없습니다.

그러나 여기서는 처음 빈 슬롯을 찾고 싶으므로 중요하지 않을 수 있습니다. 슬롯에 순서를 지정하지 않으면 빈 슬롯을 찾을 수 있습니다.

이것은 다음과 같이 수행됩니다

update slots s 
set slotValue=newValue 
WHERE s.userID = <UserID> AND slotValue IS NULL AND NOT EXISTS 
(SELECT 1 FROM slots s2 WHERE s2.userid=s.userid AND s2.slotValue IS NULL AND s2.slotID<s.slotID) 

당신이 1에서 사용자의 슬롯 번호 슬롯 테이블 (에 slotNr 필드를 추가 할 경우 ...10) 쿼리는 다음과 같이 나타납니다.

update slots s 
set slotValue=newValue 
WHERE s.userID = <UserID> AND slotValue IS NULL AND NOT EXISTS 
(SELECT 1 FROM slots s2 WHERE s2.userid=s.userid AND s2.slotValue IS NULL AND s2.slotNr<s.slotNr) 

쿼리를 실행하면 데이터베이스에서 영향을받는 행 수를 반환합니다. 모든 슬롯이 사용 중이면 반환 값은 0이고 슬롯이 업데이트 된 경우 1입니다. 이 무료 슬롯을 반환하는 경우에도, 당신은 실제로 빈 슬롯 값을 변경하는 올 때 보장은 없지만

당신이 있다는 것을,

select count(*) FROM slots 
WHERE slots.userID=<userID> AND slots.slotValue IS NULL 

를 작성하여 얼마나 많은 무료 슬롯을 찾을 수 있습니다 모든 사용 가능한 슬롯 - 해당 사용자의 슬롯 값을 추가하는 다른 작업은 마지막 사용 가능한 슬롯을 차지할 수 있습니다. 따라서 ROW_COUNT 변수를 사용하여 슬롯이 수정되었는지 여부를 확인하는 것이 가장 좋습니다.

관련 문제