2012-11-15 4 views
5

절의 IN WHERE I 항목 속성의 테이블을 가지고 있고,이 같은 구조 user_favorites의 테이블 : MySQL의 - 하위 쿼리 및

  • USER_ID
  • 좋아하는 ITEM_ID
    • ID (BOOL)

    사용자가 항목을 "즐겨 찾기"하면 항목 ID, 사용자 ID를 사용하여이 테이블에 행을 추가하고 즐겨 찾기 속성을 1로 설정합니다 ("unfavorit e "는 0으로 변경됨).

    제품 목록을 볼 때 사용자의 즐겨 찾기를 표시하는 방법을 알아 내려고하고 있습니다.

    현재 사용자 검색 입력을 기반으로 쿼리를 수행하고 제품 ID 배열을 가져옵니다. 이제 제품 정보 테이블을 만들기 위해 해당 제품들 사이에서 쿼리를 수행하고 싶습니다. 그리고이 항목이 사용자 선호도인지 여부를 포함 시키길 원합니다.

    은 이런 식으로 뭔가를 시도했다 : 물론

    select i.tid, i.name as name, i.image as image, (SELECT favorite FROM user_favorites WHERE user_id=77) as favorite 
        FROM items i 
    
        left join user_favorites ufav on (ufav.item_id = i.tid) 
        WHERE i.tid IN (79, 98, 105 . . .) 
        order by favorite DESC, name ASC 
    

    ..하지만 내가이 하위 쿼리는 1 개 이상의 행 나는 또한 이런 식으로 뭔가를 시도했습니다

    오류를 반환받을 :

    select i.tid, i.name as name, i.image as image, ufav.favorite as favorite 
        FROM items i 
        left join user_favorites ufav on (ufav.item_id = i.tid) 
        WHERE i.tid IN (79, 98, 105 . . .) AND ufav.user_id=77 
        order by favorite DESC, name ASC 
    

    . . . 그러나 이것은 (당신이 기대했던대로) 선호되는 항목 만 반환합니다. 모두의 ID 목록에있는 항목을 반환하고 싶지만 어떤 항목이 "즐겨 찾기"되지 않았는지 알고 싶습니다.

    하나의 쿼리에서이 작업을 수행 할 수 있습니까? 아니면 두 가지 별도의 쿼리를 실행하는 것이 가장 좋은 방법입니까?

  • 답변

    0

    다음과 같은 접근 방법이 있습니다.

    (
        SELECT i.tid, i.name as name, i.image, 1 AS favorite 
        FROM items i 
        LEFT JOIN user_favorites ufav on (ufav.item_id = i.tid) 
        WHERE ufav.user_id = //the user id 
        AND i.tid IN (79, 98, 105 . . .) 
    ) 
    
    UNION DISTINCT 
    
    (
        SELECT i.tid, i.name as name, i.image as image, 0 AS favorite 
        FROM items i 
        WHERE NOT EXISTS (SELECT * 
             FROM user_favorites ufav 
             WHERE ufav.item_id = i.tid 
             AND ufav.user_id = //the user id 
             AND ufav.favorite=1 
             ) 
        AND i.tid IN (79, 98, 105 . . .) 
    ) 
        ORDER BY favorite DESC , i.name ASC 
    

    이 문제가 있습니까? 내가 원했던 것처럼 작동하고있는 것 같습니다 ...

    1

    예를 들어,이 ::

    select 
    i.tid, 
    i.name as name, 
    i.image as image, 
    ifnull(favorite,false) as isFavorite 
    
    FROM items i 
    left join user_favorites ufav on (ufav.item_id = i.tid) 
    WHERE i.tid IN (79, 98, 105 . . .) and ufav.user_id=77 
        order by favorite DESC, name ASC 
    
    +0

    응답을 보내 주셔서 감사합니다. Sashi, John Woo는 정확합니다. 검색 결과에 너무 좋아하지 않는 항목이 필요합니다. – Zarwell

    1

    난 당신이 모든 사용자에 대한 모든 항목을 표시하기 원하기 때문에 여기 CROSS JOIN을 사용할 필요가 있다고 생각하십시오

    SELECT d.item_ID, d.Itemname, d.user_ID, 
         COALESCE(c.`favorite`, 0) Favorite 
    FROM 
         (
          SELECT a.item_ID, a.Itemname, b.user_ID 
          FROM  items a CROSS JOIN 
            (
             SELECT DISTINCT user_ID 
             FROM user_favorites 
            ) b 
         ) d LEFT JOIN user_favorites c 
          ON c.item_ID = d.item_ID AND 
           c.user_ID = d.user_ID 
    -- WHERE d.user_ID = 1  -- this is you condition 
    ORDER BY d.user_ID, d.Item_ID 
    
    +0

    굉장 - 고마워요! 나는이 일을 연구해야만 무슨 일이 일어나는지 알아낼 것입니다. 그러나 그것은 완벽하게 작동합니다. – Zarwell

    +0

    이것은 내 사용자 ID로 테스트하는 동안 작동하는 것처럼 보였지만 다른 ID를 사용했을 때는 작동하지 않았습니다. 나는 마침내 사용자가 적어도 하나의 항목을 "선호"(user_favorites 테이블에 행이 있음)하는 경우에만 작동한다는 것을 알게되었습니다. 다시 말해, 사용자가 항목을 선호하지 않으면 0 결과가 반환됩니다. 이 문제를 해결하는 방법에 대한 조언이 필요하십니까? – Zarwell