2010-04-28 1 views
1

Я пытаюсь отобразить список магазинов, каждый из которых содержит 3 случайных предмета из своего магазина, если у них есть 3 или более объявлений, которые активно рекламируются. У меня 3 таблицы: одна для магазинов - «Магазины», одна для листингов - «Листинги» и та, которая отслеживает активных рекламодателей - «AdShops».Выбор случайных 3 лучших объявлений в магазине для ряда активных рекламных магазинов

Используя приведенный ниже список, возвращенные данные являются случайными, однако я не получаю ровно 3 листа (строки), возвращенные в магазине.

SELECT AdShops.ID, Shops.url, Shops.image_url, Shops.user_name AS shop_name, 
     Shops.title, L.listing_id AS listing_id, L.title AS listing_title, 
     L.price as price, L.image_url AS listing_image_url, L.url AS listing_url 
FROM AdShops INNER JOIN 
     Shops ON AdShops.user_id = Shops.user_id INNER JOIN 
     Listings AS L ON Shops.user_id = L.user_id 
WHERE (Shops.is_vacation = 0 AND Shops.listing_count > 2 AND 
     L.listing_id IN 
      (SELECT TOP 3 L2.listing_id 
      FROM Listings AS L2 
      WHERE L2.listing_id IN 
       (SELECT TOP 100 PERCENT L3.listing_id 
        FROM Listings AS L3 
        WHERE (L3.user_id = L.user_id) 
       ) 
      ORDER BY NEWID() 
      ) 
     ) 
ORDER BY Shops.shop_name 

Я в тупике. У кого-нибудь есть идеи по его устранению?

Идеальное решение - это одна запись в хранилище с 3 списками (и связанными данными) в столбцах, а не в строках - это возможно?

+0

Что вы подразумеваете под 'не точно 3'? Это больше или меньше 3? –

+0

Несоответствующие результаты. Это почти как число возвращаемых результатов является случайным, а также списки ... 2 строки для магазина, 4 строки для следующего магазина, 4 строки ..., 3 строки ..., 3 ряды ..., 2 ряда ..., и т. д. Каждый раз, когда количество рядов на магазин случайное ... Я ожидаю, что последовательные 3 строки в магазине неслучайны ... Единственное, что * работает *, - это то, что магазины возвращаются в алфавитном порядке ... – Graeme

+0

Когда «ORDER BY NEWID()» удаляется, я получаю ровно 3 строки, возвращенные в магазин - почему ??? – Graeme

ответ

1

Если я не ошибаюсь, ниже запрос должен дать вам каждый user_id, имеющий как минимум 3 случайных листинга.

SELECT user_id 
     , listing_id 
FROM (
      SELECT l.user_id 
        , l.listing_id 
        , RowNumber = ROW_NUMBER() OVER (PARTITION BY l.user_id ORDER BY NEWID()) 
      FROM Listings l 
        INNER JOIN (
        SELECT user_id 
        FROM Listings 
        GROUP BY 
          user_id 
        HAVING COUNT(*) >= 3 
       ) cnt ON cnt.user_id = l.user_id 
     ) l 
WHERE l.RowNumber <= 3 
+0

Блестящий! Я слышал о методе ROW_NUMBER() OVER (PARTITION), но никогда не использовал его раньше. Большое спасибо! Я отправлю полное решение в ответ тем, кто заинтересован ... – Graeme

1

Благодаря Lieven за ключом к проблеме. Полный раствор выглядит следующим образом:

SELECT AdShops.ID, Shops.url, Shops.image_url, 
     Shops.user_name AS shop_name, Shops.title, L.listing_id AS listing_id, 
     L.title AS listing_title, L.price as price, 
     L.image_url AS listing_image_url, L.url AS listing_url 
FROM AdShops INNER JOIN 
     Shops ON AdShops.user_id = Shops.user_id INNER JOIN 
     Listings AS L ON Shops.user_id = L.user_id 
WHERE (Shops.is_vacation = 0 AND Shops.listing_count > 2 AND 
     L.listing_id IN 
      (SELECT listing_id 
      FROM  
       (SELECT l2.user_id , l2.listing_id, RowNumber = ROW_NUMBER() 
        OVER (PARTITION BY l2.user_id ORDER BY NEWID()) 
        FROM Listings l2 INNER JOIN 
         (SELECT user_id 
         FROM  Listings 
         GROUP BY user_id 
         HAVING COUNT(*) >= 3 
        ) cnt ON cnt.user_id = l2.user_id 
       ) l2 
      WHERE l2.RowNumber <= 3 and L2.user_id = L.user_id 
      ) 
     ) 
ORDER BY Shops.shop_name 

Наслаждайтесь!