Можно ли это сделать одним запросом? - PullRequest
1 голос
/ 24 ноября 2010
Table: category  
-- idcategory (PK)  
-- idmember (FK: member that owns category)  

Table: category_shared UNIQUE (idcategory,idmember)   
-- idcategory (FK:referencing table category)  
-- idmember (FK:member being shared with)  

Table: last_viewed UNIQUE (idcategory,idmember)   
-- idcategory (FK:referencing table category)  
-- idmember (FK)  

Я хочу один запрос, который извлекает все категории, к которым он принадлежал или принадлежал участнику, и последний раз, когда эта категория была просмотрена.Вот что я попробовал:

SELECT * FROM (category 
LEFT JOIN category_shared USING (idmember))
INNER JOIN last_viewed ON 
    category.idcategory=last_viewed.idcategory OR 
    category_shared.idcategory=last_viewed.idcategory
WHERE category.idmember = '$member_id' OR category_shared.idmember = '$member_id'

Но он возвращает SIX идентичных строк для каждой уникальной категории.Вся эта структура базы данных была PITA с самого начала, поэтому я открыт для предложений по улучшению схемы.

Ответы [ 4 ]

3 голосов
/ 25 ноября 2010

Да, хорошо, половина ваших проблем связана с отсутствием разрешенной модели данных, и это повсеместно вызовет проблемы в SQL;если вы исправите это, SQL будет намного проще.Другая половина не в состоянии эффективно использовать SQL.

  1. Вы не опубликовали информацию о других таблицах, поэтому я не могу дать вам достаточно точную DM, я собираюсь простоиз того, что вы предоставили, и, конечно, сделали огромные предположения о других связанных таблицах, которые, скорее всего, неверны.Если вы предоставите информацию, я могу предоставить точную DM.

    • Является ли Категория независимой или «принадлежит» только одному Участнику?
      • Моделируется: «Нет».
    • На каком основании категория «разделяется»?
      • Моделируется: совместное использование - это то же самое, что владение;общая категория - это просто категория, которой владеют более одного члена
    • Тогда в чем же разница между категорией "принадлежащих" и категорией "общего доступа"?
    • Мы не знаем, для чего нужны Категории (Предметы?).В каком случае, почему категории, а не субъекты принадлежат / разделяются участниками?
    • Ваша категория, если она принадлежит, на самом деле не должна называться Category, а скорее как CategoryOwned.
    • Я не могупосмотрите, как CategoryViewed показывает все виды;он разрешает только один (последний?) просмотр для каждого члена.Где находится ViewDate?
      • Моделируется: как журнал просмотров.Если вам нужно только одно (последнее) представление для каждого участника, удалите ViewDate из PK.

    Промежуточная модель данных

  2. Выполнение не очень хорошая идеяСоюзы и т. Д., Если вам абсолютно не нужно.Прямо сейчас данные маленькие;когда база данных велика, вы непременно почувствуете влияние создаваемых рабочих таблиц;заполнены;уничтожены.Таким образом, в соответствии с вашими требованиями, нет необходимости в Unions, Distincts, рабочих таблицах и т. Д. Но DM создает проблемы.

  3. SQL.Я не могу понять, каким образом ваш SQL (или любой другой ответ) получает ваше требование «в последний раз эту категорию просматривали [любой участник]».Кроме того, вы всегда должны пытаться получить правильный SQL-код (возвращая правильный набор данных) для каждого набора, до объединения и т. Д .: вы этого не сделали;Вот почему у вас есть повторяющиеся строки.Использование DISTINCT - глупый способ решить проблему;вместо этого вы правы в поиске понимания.

  4. Я не буду пытаться предоставить SQL для вашей модели.Вот SQL для Временной модели данных.Очевидно, что это намного, намного дешевле, чем союзы:

    <code>SELECT  [Member]   = Member.Name,
            [Category  = Category.Name,
            [LastView] = ( SELECT MAX(ViewDate)
                FROM  CategoryView
                WHERE CategoryId = cm.CategoryId
                )
    FROM  CategoryMember cm,
          Member         m,
          Category       c
    WHERE cm.MemberId  = '$MemberId'
    AND   m.MemberId   = cm.MemberId
    AND   c.CategoryId = cm.CategoryId
0 голосов
/ 24 ноября 2010

Присоединиться к категории непосредственно к last_viewed, поскольку вы показываете данные только из этих таблиц,

Используйте Where IN category_shared для ограничения данных

0 голосов
/ 24 ноября 2010
(SELECT date_viewed,category.idcategory FROM category INNER JOIN last_viewed USING (idcategory,idmember) WHERE category.idmember='$member_id')
    UNION
(SELECT date_viewed,category_shared.idcategory FROM category_shared INNER JOIN last_viewed USING (idcategory,idmember) WHERE category_shared.idmember='$member_id')

Это то, чем я в конечном итоге воспользовался, на случай, если кто-то столкнется с таким случаем. Цените вклад!

0 голосов
/ 24 ноября 2010

Если ваша единственная проблема - возвращение нескольких идентичных строк, то DISTINCT должен выполнить эту работу.

Если это вызывает у вас проблемы с производительностью (не должно быть, если количество повторяющихся строк соответствует указанному вами значению), обратитесь с жалобой к поставщику СУБД или получите более качественную СУБД.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...