繁体   English   中英

SQL左或右联接一对多分页

[英]Sql Left or Right Join One To Many Pagination

我有一个主表,并通过左外部或右外部外部联接来联接其他表。主表的一行在联接查询中有30多个行。 我尝试分页。 但是问题是我不知道一个主表行结果将返回多少行。

范例:

主表的第一行结果在我的查询中为40行。 主表第二行结果为120行。

问题(问题)更新:对于分页,我需要给pagesize选择结果计数。 但是我不知道选择结果的正确数量。 例如,我给出的页面编号为1,页面大小为50,因此我无法获得正确的结果。我需要为我的主表前10个结果给出正确的页面大小。 也许对于前10行,结果行数为200,但我的页面大小为50,这就是问题所在。

我正在使用Sql2014。我的ASP.NET项目需要它,但并不重要。

样本更新:

这就像搜索酒店进行预订。 您的主表是酒店表。 另外还有(可传播的)图像,(可传播的)视频,(可放置的)位置以及(可评论的)注释,它们多于一行,并且与酒店具有一对多的关系。 对于一家酒店,所有信息的结果都将为100、50或10行。 我想对这家酒店的结果进行分页。 我需要始终获得20或30或50家酒店才能在我的项目中发挥作用。

示例查询UPDATE:

   SELECT  
      *
   FROM
      KisiselCoach KC
         JOIN WorkPlace WP
            ON KC.KisiselCoachId = WP.WorkPlaceOwnerId
         JOIN Album A
            ON KC.KisiselCoachId = A.AlbumId
            JOIN Media M
               ON A.AlbumId = M.AlbumId
         LEFT JOIN Rating R
            ON KC.KisiselCoachId = R.OylananId 
         JOIN FrUser Fr
            ON KC.CoachId = Fr.UserId 
         JOIN UserJob UJ
            ON KC.KisiselCoachId = UJ.UserJobOwnerId 
            JOIN Job J
               ON UJ.JobId = J.JobId 
         JOIN UserExpertise UserEx
            ON KC.KisiselCoachId = UserEx.UserExpertiseOwnerId
            JOIN Expertise Ex
               ON UserEx.ExpertiseId = Ex.ExpertiseId




Hotel Table : 
HotelId   HotelName
1         Barcelona
2         Berlin


Media Table :
MediaID   MediaUrl      HotelId
1         www.xxx.com   1
2         www.xxx.com   1
3         www.xxx.com   1
4         www.xxx.com   1


Location Table :
LocationId   Adress          HotelId 
1            xyz, Berlin     1
2            xyz, Nice       1
3            xyz, Sevilla    1
4            xyz, Barcelona  1


Comment Table :
CommentId   Comment             HotelId
1           you are cool        1
2           you are great       1
3           you are bad         1
4           hmm you are okey    1

这只是样品! 我的数据库中有9999999家酒店。 想象一下,一家酒店也许有100张图片,也许是零张。 我不知道这一点。 我的结果需要20间饭店(分页)。 但是20家酒店意味着可能有1000行或100行。

首先,查询的可读性差/表关系不好。 我已经更新并缩进以尝试显示表/如何在层次相对论中相关。

您还想分页,让我们回到这一点。 您是否打算将每条记录显示为一个可能的项目,还是打算显示“父”级别的数据集...例如,因此每个媒体,每个用户或任何对象只有一个实例,则一旦输入选择您将显示该实体的详细信息? 如果是这样,我将在顶层进行DISTINCT的查询,或者至少获取具有必须在下一层显示的子记录的count(*)的几列。

此外,混合内部,左侧和右侧连接可能会造成混淆。 通常,右联接意味着您需要联接右表中的记录。 是否可以将其重写为将所有必需的表都保留在左侧,并且不需要将其左联接到辅助表中?

澄清所有这些关系绝对可以帮助您摆脱分页。 我会检查评论,但如果篇幅太长,我会用其他详细信息(而不是冗长的评论)来编辑您的原始帖子问题。

这是我的SOMEWHAT澄清查询,重写为我认为您数据库中的关系。 注意我的缩进显示表A-> B-> C-> D的可读性。 所有这些都是(INNER)JOIN,表示它们在所有各自的表之间都必须具有匹配项。 如果某些东西不总是存在的,它们将被更改为LEFT JOINs

SELECT  
      *
   FROM
      KisiselCoach KC
         JOIN WorkPlace WP
            ON KC.KisiselCoachId = WP.WorkPlaceOwnerId
         JOIN Album A
            ON KC.KisiselCoachId = A.AlbumId
            JOIN Media M
               ON A.AlbumId = M.AlbumId
         LEFT JOIN Rating R
            ON KC.KisiselCoachId = R.OylananId 
         JOIN FrUser Fr
            ON KC.CoachId = Fr.UserId 
         JOIN UserJob UJ
            ON KC.KisiselCoachId = UJ.UserJobOwnerId 
            JOIN Job J
               ON UJ.JobId = J.JobId 
         JOIN UserExpertise UserEx
            ON KC.KisiselCoachId = UserEx.UserExpertiseOwnerId
            JOIN Expertise Ex
               ON UserEx.ExpertiseId = Ex.ExpertiseId

查询的可读性是您自己和/或任何协助或关注您的人的BIG帮助。 由于在相应的联接附近没有“ on”子句,因此很难理解。

另外,这是您的PRIMARY表,其余为查找参考表。

每条评论的增加

好的,所以我更新了一个查询,该查询似乎与示例数据以及您想要的帖子没有上下文。 就是说,我将仅从酒店列表和每家酒店的事物计数(*)开始,以便您可以详细说明您拥有多少东西。 就像是

select
      H.HotelID,
      H.HotelName,
      coalesce( MedSum.recs, 0 ) as MediaItems,
      coalesce( LocSum.recs, 0 ) as NumberOfLocations,
      coalesce( ComSum.recs, 0 ) as NumberOfLocations
   from
      Hotel H
         LEFT JOIN
         ( select M.HotelID, 
                  count(*) recs
              from Media M
              group by M.HotelID ) MedSum
            on H.HotelID = MedSum.HotelID
         LEFT JOIN
         ( select L.HotelID, 
                  count(*) recs
              from Location L
              group by L.HotelID ) LocSum
            on H.HotelID = LocSum.HotelID
         LEFT JOIN
         ( select C.HotelID, 
                  count(*) recs
              from Comment C
              group by C.HotelID ) ComSum
            on H.HotelID = ComSum.HotelID
   order by
      H.HotelName
   --- apply any limit per pagination

现在,这将返回每个顶级酒店,以及每个酒店可能存在或不存在的单个事物的总计数,因此每个子检查都是LEFT-JOIN。 展示20家不同酒店的页面。 现在,只要一个人选择了一家旅馆,您就可以深入了解该旅馆的位置,媒体和评论。

现在,尽管可以进行此工作,但是每次查询都必须进行这些计数可能会非常耗时。 您可能希望将计数器列添加到您的主要酒店表中,以表示此处要执行的计数。 然后,通过每晚的某个过程,您可以一次更新计数,以便在所有历史记录中进行计数,然后仅更新自先前日期以来具有新活动的那些旅馆的计数。 不像您一天要有1,000,000条新图像,新位置,新评论的帖子,而是22,000条,那是您要重新更新计数的唯一酒店记录。 仅基于添加的最新条目,每个增量周期都会很短。 对于网络而言,在可行的情况下节省一些预先汇总的计数,总和等可以节省大量时间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM