这可以在一个查询中完成吗?

发布于 2024-10-04 03:27:13 字数 801 浏览 1 评论 0原文

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'

但它为每个唯一类别返回六个相同的行。整个数据库结构从一开始就是 PITA,因此我愿意接受有关更好模式的建议。

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)  

I want a single query that pulls all categories shared or owned for a member and the last time that category was viewed. This is what I tried:

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'

But it's returning SIX of the identical rows for each unique category. This whole database structure has been a PITA from the get-go so I'm open to suggestions for a better schema.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

明明#如月 2024-10-11 03:27:13

是的,一半的问题是由于没有解决数据模型造成的,这会导致 SQL 各处出现问题;如果你解决了这个问题,SQL 就会容易得多。另一半是无法有效地使用 SQL。

  1. 您还没有发布其他表格的信息,所以我无法给您一个相当准确的DM,我只是根据您提供的内容进行,当然对其他相关表格做出了巨大的假设,这些表格是最重要的可能不正确。如果您提供信息,我可以提供准确的 DM。

    • 某个类别是独立的还是仅由一名成员“拥有”?
      • 建模:“否。”
    • 类别“共享”的依据是什么?
      • 模型化:共享与所有权相同;共享类别只是由多个成员拥有的类别
    • 那么,“拥有”类别和“共享”类别之间有什么区别?
    • 我们不知道类别的用途(主题?)。在这种情况下,为什么会员拥有/共享类别而不是主题?
    • 您的类别(如果已拥有)确实不应称为“类别”,而应称为“CategoryOwned”之类的名称。
    • 我看不到 CategoryViewed 如何显示所有视图;它只允许每个会员一次(最后一次?)查看。 ViewDate 在哪里?
      • 建模:作为视图日志。如果您只希望每个成员一次(最后一次)查看,请从 PK 中删除 ViewDate。

    临时数据模型

  2. < p>执行 Unions 等并不是一个好主意,除非绝对必要。目前数据还很小;当数据库很大时,你一定会感受到创建工作表的效果;充满;被毁了。到目前为止,与您的要求相比,不需要 Unions、Distincts、工作表等。但是 DM 确实存在问题。

  3. SQL。我看不到您的 SQL(或任何其他答案)如何检索您对“[任何成员]上次查看该类别”的要求。此外,在联合等之前,您应该始终尝试使每个集合的 SQL 正确(返回正确的数据集):您还没有这样做;这就是为什么你有重复的行。使用 DISTINCT 是解决问题的愚蠢方法;你寻求理解是正确的。

  4. 我不会尝试为您的模型提供 SQL。以下是提供的临时数据模型的 SQL。显然,这比 Unions 便宜得多:

    SELECT [Member] = Member.Name,
            [类别 = 类别.名称,
            [最后查看] = ( 选择 MAX(查看日期)
                来自类别查看
                WHERE CategoryId = cm.CategoryId
                )
    FROM 类别成员 cm,
          会员米,
          c类
    WHERE cm.MemberId = '$MemberId'
    AND m.MemberId = cm.MemberId
    AND c.CategoryId = cm.CategoryId

Yes, well, half your problems are due to not having a resolved Data Model, and that will cause problems in SQL everywhere; if you fix that, the SQL will be much easier. The other half is not being able to use SQL effectively.

  1. You have not posted info re the other tables, so I can't give you a reasonably accurate DM, I am going just from what you have provided, and of course made huge assumptions about the other related tables, which are most probably incorrect. If you provide the info, I can provide an accurate DM.

    • Is a Category Independent or "owned" by only one Member ?
      • Modelled: "No."
    • On what basis is a Category "shared" ?
      • Modelled: sharing is the same as ownership; a shared Category is simply one that is owned by more than one Member
    • Then, what is the difference between an "owned" Category and a "shared" Category ?
    • We do not know what the Categories are for (Subjects ?). In which case why are Categories, not Subjects, owned/shared by Members ?
    • Your Category, if it is owned, really should not be called Category, rather something like CategoryOwned.
    • I cannot see how CategoryViewed shows all the Views; it allows only one (the last ?) view per Member. Where is the ViewDate ?
      • Modelled: As a log of Views. If you want only one (the last) view per Member, remove ViewDate from the PK.

    Interim Data Model

  2. It is not a good idea to perform Unions, etc, unless you absolutely have to. Right now the data is small; when the database is large, you will certainly feel the effects of the work tables being created; filled; destroyed. So far from your requirement, there is no need for Unions, Distincts, worktables, etc. But the DM does present problems.

  3. SQL. I cannot see how your SQL (or any of the other answers) retrieves your requirement of "the last time that category was viewed [by any Member]". Additionally, you should always try to get your SQL correct (returning the correct set of data) for each set, before Unioning, etc: you have not done that; that is why you have duplicate rows. Using DISTINCT is a stupid way to fix the problem; you are correct in seeking understanding instead.

  4. I won't attempt to provide the SQL for your model. Here is the SQL for the Interim Data Model provided. Obviously, this is much, much cheaper than Unions:

    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

最初的梦 2024-10-11 03:27:13

如果您唯一的问题是返回多个相同的行,那么 DISTINCT 应​​该可以完成这项工作。

如果这会给您带来性能问题(如果重复行的数量如您所指示,则不应出现),请向您的 DBMS 供应商投诉或获取更好的 DBMS。

If your only problem is multiple identical rows returned, then DISTINCT should do the job.

If that gives you performance problems (it shouldn't if the numbers of duplicate rows are as you indicate), complain with your DBMS vendor or get a better DBMS.

卖梦商人 2024-10-11 03:27:13

将类别直接加入到last_viewed,因为您仅显示这些表中的数据,

请使用Where INcategory_shared来限制数据

Join Category Directly to last_viewed as you are only showing data from those tables,

Use a Where IN category_shared to restrict the data

喜爱皱眉﹌ 2024-10-11 03:27:13
(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')

这就是我最终使用的,以防有人遇到这样的情况。感谢您的投入!

(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')

This is what I ended up using, in case someone comes across a case like this. Appreciate the input!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文