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,所以我愿意接受更好的架构建议。
答案 0 :(得分:3)
是的,好吧,你的一半问题是由于没有一个已解决的数据模型,这会导致SQL无处不在;如果你修复它,SQL会更容易。另一半无法有效使用SQL。
你没有在其他表中发布信息,所以我不能给你一个相当准确的DM,我只是从你提供的内容,当然对其他相关表做出了很大的假设,这很可能是不正确的。如果您提供信息,我可以提供准确的DM。
执行联盟等不是一个好主意,除非你绝对必须这样做。现在数据很小;当数据库很大时,你肯定会感受到正在创建的工作表的影响;填充;销毁。从您的要求到目前为止,不需要工会,区别,工作表等。但DM确实存在问题。
SQL。我无法看到您的SQL(或任何其他答案)如何检索“上次[任何成员]查看该类别”的要求。此外,在Unioning等之前,你应该总是尝试让每个集合的SQL正确(返回正确的数据集):你还没有这样做;这就是你有重复行的原因。使用DISTINCT是一种解决问题的愚蠢方法;你在寻求理解方面是正确的。
我不会尝试为您的模型提供SQL。这是提供的临时数据模型的SQL。显然,这比联盟便宜得多:
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
答案 1 :(得分:0)
如果您唯一的问题是返回了多个相同的行,那么DISTINCT应该完成这项工作。
如果这会给您带来性能问题(如果重复行的数量与您指示的一样,则不应该这样),请向您的DBMS供应商投诉或获得更好的DBMS。
答案 2 :(得分:0)
将类别直接加入last_viewed,因为您只显示这些表中的数据,
使用Where IN
category_shared限制数据
答案 3 :(得分:0)
(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')
这是我最终使用的,以防有人遇到这样的情况。感谢输入!