2015-05-29 13 views
7

Ông chủ của tôi đã cho tôi một cái bàn duy nhất.Đệ trình trên một phụ huynh nhiều người đến bàn với cha mẹ

 
Related_Items_Table 

Item  | Accessory 
--------------------- 
TV   | Antennae 
TV   | Power Cord 
TV   | Remote 
Laptop  | Power Cord 
Laptop  | Carrying Case 
Camera  | Carrying Case 
Camera  | Lens 
iPod  | Headphones 

Cách tốt nhất để mô tả những gì ông chủ của tôi muốn cho kết quả là đi qua quy trình.

  1. Người dùng tìm kiếm TV.

  2. TV và phụ kiện cho TV là Antennae, Dây nguồn & Điều khiển từ xa.

  3. Các phụ kiện Antennae, Power Cord & từ xa hiện đang sử dụng để tìm mặt hàng liên quan khác. Dây điện cũng là một phụ kiện cho máy tính xách tay. Ăng ten & Từ xa không phải là phụ kiện cho bất kỳ mục nào khác.

  4. Mục Máy tính xách tay hiện được sử dụng để tìm phụ kiện của mặt hàng đó, là Dây nguồn & Hộp đựng.

  5. Phụ kiện Dây nguồn & Hộp đựng hiện đang được sử dụng để tìm các mục liên quan khác. Dây điện không tìm thấy vật phẩm mới (chúng tôi đã biết Dây nguồn được kết hợp với TV & Máy tính xách tay). Hộp đựng cũng là phụ kiện cho Máy ảnh.

  6. Các mục Máy ảnh bây giờ được sử dụng để tìm các phụ kiện của mục đó, mà được đựng & Lens.

  7. Các phụ kiện Hộp đựng & Ống kính hiện được sử dụng để tìm các mục khác có liên quan . Hộp đựng & Ống kính không tìm thấy vật phẩm mới (chúng tôi đã biết Hộp đựng được kết hợp với Máy tính xách tay).

  8. Không tìm thấy mục mới để tiếp tục chuỗi tìm kiếm. Danh sách cuối cùng được trả lại.

 
Final List 

Item  | Accessory 
--------------------- 
TV   | Antennae 
TV   | Power Cord 
TV   | Remote 
Laptop  | Power Cord 
Laptop  | Carrying Case 
Camera  | Carrying Case 
Camera  | Lens 

cách tốt nhất để xử lý vấn đề này là gì? Tôi không chắc thuật ngữ chính xác sẽ là gì cho điều này vì vậy có lẽ tôi đã bỏ lỡ nó trong các tìm kiếm của mình. Mọi lời khuyên đều được đánh giá cao.

+2

Không thể giải được mà không có vòng lặp. Nó là đệ quy vô hạn. –

Trả lời

0

tôi sẽ làm một cái gì đó giống như pesudocode này: giả

insert into Final_List 
all the records that match the item in Related_Items_Table 

WHILE 1=1 
BEGIN 
    Insert into Final List 
    select NextLevel.* 
    from Related_Items_Table 
    join Related_Items_Table NextLevel 
    on Related_Items_Table.Accessory = NextLevel.Item 
    where the nextlevel.item and nextlevel.accesory not already in Final List 
    if @@Rowcount = 0 
     break 
END 
0

Brian Pressler là khá chặt chẽ, tiết kiệm cho một vài vấn đề với việc tham gia. Đây là những gì tôi nghĩ rằng điều này có vẻ như:

-- The sample data from the problem. 
declare @SearchString varchar(32) = 'TV'; 
declare @RelatedItemsTable table 
(
    [Item] varchar(32), 
    [Accessory] varchar(32) 
); 
insert @RelatedItemsTable values 
    ('TV', 'Antennae'), 
    ('TV', 'Power Cord'), 
    ('TV', 'Remote'), 
    ('Laptop', 'Power Cord'), 
    ('Laptop', 'Carrying Case'), 
    ('Camera', 'Carrying Case'), 
    ('Camera', 'Lens'), 
    ('iPod', 'Headphones'); 

-- This table will hold your results. 
declare @SearchResults table 
(
    [Item] varchar(32), 
    [Accessory] varchar(32) 
); 

-- Base case: look for any item or accessory that matches the search string. 
-- I'm not sure whether you want to search items only or accessories also; 
-- adjust as needed. 
insert @SearchResults 
select * 
from 
    @RelatedItemsTable 
where 
    [Item] like @SearchString or 
    [Accessory] like @SearchString; 

while @@rowcount > 0 
begin 
    -- The recursive case: look for new records where... 
    insert @SearchResults 
    select 
     [New].[Item], 
     [New].[Accessory] 
    from 
     @RelatedItemsTable [New] 
     inner join @SearchResults [Old] on 
      -- ... the new record is an item using the same kind of accessory as 
      -- an existing item, or... 
      [New].[Accessory] = [Old].[Accessory] or 

      -- ... the new record is an accessory for the same kind of item as an 
      -- existing accessory, and... 
      [New].[Item] = [Old].[Item] 
    where 
     -- ... this record doesn't yet appear in the result set. 
     not exists 
     (
      select 1 
      from 
       @SearchResults [Existing] 
      where 
       [Existing].[Accessory] = [New].[Accessory] and 
       [Existing].[Item] = [New].[Item] 
     ); 
end; 

select * from @SearchResults; 

SQL Server không có một cơ chế cho các truy vấn đệ quy-the recursive CTE -Nhưng tôi đã không thể thực hiện ví dụ này sử dụng một trong những vì tôi không thể thực hiện NOT EXISTS một phần của truy vấn trên.

0

Tôi không thể làm điều đó với CTE như tôi đã nói.Lý do tại sao được giải thích ở đây: Prevent recursive CTE visiting nodes multiple times

Vì vậy, đây là một thời trang theo cách cũ

DECLARE @MyTable TABLE(Item NVARCHAR(50), Accessory NVARCHAR(50)) 
DECLARE @Result TABLE(Item NVARCHAR(50), Accessory NVARCHAR(50), LinkedItem NVARCHAR(50), Done int) 

INSERT INTO @MyTable 
VALUES 
('TV', 'Antennae'), 
('TV', 'Power Cord'), 
('TV', 'Remote'), 
('Laptop', 'Power Cord'), 
('Laptop', 'Carrying Case'), 
('Camera', 'Carrying Case'), 
('Camera', 'Lens') 


DECLARE @NbIteration INT = 0 

INSERT INTO @Result 
SELECT t.Item, 
     t.Accessory, 
     LinkedItem.Item, 
     @NbIteration     
FROM @MyTable AS t 
LEFT JOIN @MyTable AS LinkedItem ON t.Accessory = LinkedItem.Accessory 
WHERE t.Item = 'TV' 


WHILE(@@ROWCOUNT > 0) 
BEGIN 
    SELECT @NbIteration = @NbIteration + 1 

    INSERT INTO @Result 
    SELECT t.Item, 
      t.Accessory, 
      LinkedItem.Item, 
      @NbIteration   
    FROM @Result AS r 
    INNER JOIN @MyTable AS t ON r.LinkedItem = t.Item 
    LEFT JOIN @MyTable AS LinkedItem ON t.Accessory = LinkedItem.Accessory 
    WHERE r.Done = @NbIteration - 1 
    AND NOT EXISTS(SELECT TOP 1 1 FROM @Result AS Sub WHERE t.Item = Sub.Item) --don't go back to records already done 

END 

SELECT DISTINCT Item, Accessory 
FROM @Result 
0

Nếu bạn không không thích sử dụng một tuyên bố GOTO cho vòng lặp bạn đang cố gắng để đạt được, đây là một giải pháp:

DECLARE @search VARCHAR(50) = 'TV' 

--Get initial resultset 
DECLARE @table TABLE (item VARCHAR(50), accessory VARCHAR(50)) 
INSERT INTO @table 
SELECT 
    items.* 
FROM 
    items 
WHERE 
    item LIKE @search 

--declare the variables used for checking if we have any new results 
DECLARE @intCount INT = (SELECT COUNT(*) FROM @table) 
DECLARE @intNewCount INT = (SELECT COUNT(*) FROM @table) 

--The infamous GOTO label 
START: 
    --Store the count of items 
    SET @intCount = (SELECT COUNT(*) FROM @table) 

    --Insert any matching rows for accessory = accessory, excluding ones already added 
    INSERT INTO @table 
     (item, accessory) 
    SELECT 
     item, accessory 
    FROM 
     items 
    WHERE 
     accessory IN (SELECT accessory FROM @table) 
    AND NOT EXISTS(SELECT TOP 1 1 FROM @table t WHERE t.item = items.item AND t.accessory = items.accessory) 

    --Now Insert any matching rows for item = item, excluding ones already added 
    INSERT INTO @table 
     (item, accessory) 
    SELECT 
     item, accessory 
    FROM 
     items 
    WHERE 
     item IN (SELECT item FROM @table) 
    AND NOT EXISTS(SELECT TOP 1 1 FROM @table t WHERE t.item = items.item AND t.accessory = items.accessory) 

    --Set the new count 
    SET @intNewCount = (SELECT COUNT(*) FROM @table) 
--Check if there's been any added during this iteration, if there are, repeat! 
IF @intCount <> @intNewCount GOTO START; 

--Finished 
SELECT * FROM @table 

tôi thấy hầu hết các câu trả lời khác có một vòng lặp trong khi, nghĩ rằng tôi chỉ muốn trộn nó lên :) Tested trong SQL2008

1

Dường như presen bảng của bạn ts một đồ thị vô hướng và bạn cần phải đi qua biểu đồ này bắt đầu từ mục Người dùng đã tìm kiếm.

Cân nhắc sử dụng breadth-first search (BFS) algorithm.

Mọi nút được truy cập là danh sách kết quả bạn cần.

+0

Trong khi liên kết này có thể trả lời câu hỏi, tốt hơn nên bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. Câu trả lời chỉ liên kết có thể trở thành không hợp lệ nếu trang được liên kết thay đổi. - [Từ đánh giá] (/ đánh giá/bài đăng chất lượng thấp/13703724) – techspider

+0

@techspider: Câu trả lời cho biết tên của thuật toán nổi tiếng, liên kết đến mô tả đầy đủ hơn và một số ghi chú về lý do và cách thức áp dụng không có nghĩa là "chỉ liên kết". –

Các vấn đề liên quan