繁体   English   中英

SQL分页查询顺序

[英]SQL Pagination Query with order by

我正在尝试编写一个查询,该查询可提取多个字段并为它们分配别名。 别名之一实际上是两个字段的总和。 这实际上是我最大的问题,因为该别名是排序时可能使用的“字段”之一,否则我可能会删除所有别名而不会遇到此问题。 无论如何,我需要能够以编程方式传递要订购的字段。 但是由于我需要使用SQL进行分页,因此无法使用LIMIT的优美功能,而必须使用子查询。

这是大问题出现的地方。因为我绝对必须在子查询中选择至少2列(因为出于限制的目的我需要ID字段,而总和别名是按字段排序),所以我不能使用由于您只能以这种方式返回一个字段,因此将其作为“ And ID Not In(子查询)”。 因此,我将向您展示我的代码,然后解释我得到的结果。

SELECT     TOP (50) dbo.tblMailList.mail_ID AS Expr1, dbo.tblMailList.mail_NameTitle AS Expr2, dbo.tblMailList.mail_FirstName AS Expr3, 
                      dbo.tblMailList.mail_LastName AS Expr4, dbo.tblMailList.mail_Company AS Expr5, dbo.tblMailList.mail_Institution AS Expr6, 
                      SUM(dbo.tblItem.item_pr + dbo.tblItem.item_premium) AS Expr7, dbo.tblMailList.mail_Comp_Art, dbo.tblMailList.mail_Comp_IndArt, 
                      dbo.tblMailList.mail_Comp_GenAm, dbo.tblMailList.mail_Comp_Fire, dbo.tblMailList.mail_Comp_Jewelry, dbo.tblMailList.mail_Comp_Ceramic, 
                      dbo.tblMailList.mail_Interest
FROM         (SELECT     TOP (50) tblMailList_1.mail_ID AS Expr1, tblMailList_1.mail_NameTitle AS Expr2, tblMailList_1.mail_FirstName AS Expr3, 
                                              tblMailList_1.mail_LastName AS Expr4, tblMailList_1.mail_Company AS Expr5, tblMailList_1.mail_Institution AS Expr6, 
                                              SUM(tblItem_1.item_pr + tblItem_1.item_premium) AS Expr7, tblMailList_1.mail_Comp_Art, tblMailList_1.mail_Comp_IndArt, 
                                              tblMailList_1.mail_Comp_GenAm, tblMailList_1.mail_Comp_Fire, tblMailList_1.mail_Comp_Jewelry, tblMailList_1.mail_Comp_Ceramic, 
                                              tblMailList_1.mail_Interest
                       FROM          dbo.tblItem AS tblItem_1 INNER JOIN
                                              dbo.tblBidder AS tblBidder_1 ON tblItem_1.item_bidder_number = tblBidder_1.bidder_number AND 
                                              tblItem_1.item_sale_id = tblBidder_1.bidder_sale_id INNER JOIN
                                              dbo.tblMailList AS tblMailList_1 ON tblBidder_1.bidder_mail_id = tblMailList_1.mail_ID
                       WHERE      (tblMailList_1.mail_Comp_Art <> '1' OR
                                              tblMailList_1.mail_Comp_Art IS NULL) AND (tblMailList_1.mail_Comp_IndArt <> '1' OR
                                              tblMailList_1.mail_Comp_IndArt IS NULL) AND (tblMailList_1.mail_Comp_GenAm <> '1' OR
                                              tblMailList_1.mail_Comp_GenAm IS NULL) AND (tblMailList_1.mail_Comp_Fire <> '1' OR
                                              tblMailList_1.mail_Comp_Fire IS NULL)
                       GROUP BY tblMailList_1.mail_Company, tblMailList_1.mail_Institution, tblMailList_1.mail_LastName, tblMailList_1.mail_FirstName, 
                                              tblMailList_1.mail_NameTitle, tblMailList_1.mail_ID, tblMailList_1.mail_Comp_Art, tblMailList_1.mail_Comp_IndArt, 
                                              tblMailList_1.mail_Comp_GenAm, tblMailList_1.mail_Comp_Fire, tblMailList_1.mail_Interest, tblMailList_1.mail_Comp_Jewelry, 
                                              tblMailList_1.mail_Comp_Ceramic
                       ORDER BY Expr7 DESC) AS tblLimiter INNER JOIN
                      dbo.tblMailList ON NOT (tblLimiter.Expr1 = dbo.tblMailList.mail_ID) INNER JOIN
                      dbo.tblBidder ON dbo.tblBidder.bidder_mail_id = dbo.tblMailList.mail_ID INNER JOIN
                      dbo.tblItem ON dbo.tblItem.item_bidder_number = dbo.tblBidder.bidder_number AND dbo.tblItem.item_sale_id = dbo.tblBidder.bidder_sale_id
WHERE     (dbo.tblMailList.mail_Comp_Art <> '1' OR
                      dbo.tblMailList.mail_Comp_Art IS NULL) AND (dbo.tblMailList.mail_Comp_IndArt <> '1' OR
                      dbo.tblMailList.mail_Comp_IndArt IS NULL) AND (dbo.tblMailList.mail_Comp_GenAm <> '1' OR
                      dbo.tblMailList.mail_Comp_GenAm IS NULL) AND (dbo.tblMailList.mail_Comp_Fire <> '1' OR
                      dbo.tblMailList.mail_Comp_Fire IS NULL) AND (NOT (dbo.tblMailList.mail_ID = tblLimiter.Expr1))
GROUP BY dbo.tblMailList.mail_Company, dbo.tblMailList.mail_Institution, dbo.tblMailList.mail_LastName, dbo.tblMailList.mail_FirstName, 
                      dbo.tblMailList.mail_NameTitle, dbo.tblMailList.mail_ID, dbo.tblMailList.mail_Comp_Art, dbo.tblMailList.mail_Comp_IndArt, 
                      dbo.tblMailList.mail_Comp_GenAm, dbo.tblMailList.mail_Comp_Fire, dbo.tblMailList.mail_Interest, dbo.tblMailList.mail_Comp_Jewelry, 
                      dbo.tblMailList.mail_Comp_Ceramic
ORDER BY Expr7 DESC

这个问题是,如果子查询选择前0,则不会返回任何内容,这很明显,但是我需要尝试一下,因为我已经做了很多尝试。 选择50时,它将返回50行,且SUM总数较大。 当选择100时,它返回相同的50(因为最初的前50个),但是SUM总数是原来的两倍...

现在,我也将其放在“ FROM”语句被反转的位置,其顺序与子查询本身的顺序相同,如下所示:

SELECT     TOP (50) tblMailList.mail_ID AS Expr1, tblMailList.mail_NameTitle AS Expr2, tblMailList.mail_FirstName AS Expr3, 
                      tblMailList.mail_LastName AS Expr4, tblMailList.mail_Company AS Expr5, tblMailList.mail_Institution AS Expr6, 
                      SUM(tblItem.item_pr + tblItem.item_premium) AS Expr7, tblMailList.mail_Comp_Art, tblMailList.mail_Comp_IndArt, tblMailList.mail_Comp_GenAm, 
                      tblMailList.mail_Comp_Fire, tblMailList.mail_Comp_Jewelry, tblMailList.mail_Comp_Ceramic, tblMailList.mail_Interest
FROM         dbo.tblItem AS tblItem INNER JOIN
                      dbo.tblBidder AS tblBidder ON tblItem.item_bidder_number = tblBidder.bidder_number AND tblItem.item_sale_id = tblBidder.bidder_sale_id INNER JOIN
                      dbo.tblMailList AS tblMailList ON tblBidder.bidder_mail_id = tblMailList.mail_ID LEFT OUTER JOIN
                          (SELECT     TOP (50) tblMailList_1.mail_ID AS Expr1, tblMailList_1.mail_NameTitle AS Expr2, tblMailList_1.mail_FirstName AS Expr3, 
                                                   tblMailList_1.mail_LastName AS Expr4, tblMailList_1.mail_Company AS Expr5, tblMailList_1.mail_Institution AS Expr6, 
                                                   SUM(tblItem_1.item_pr + tblItem_1.item_premium) AS Expr7, tblMailList_1.mail_Comp_Art, tblMailList_1.mail_Comp_IndArt, 
                                                   tblMailList_1.mail_Comp_GenAm, tblMailList_1.mail_Comp_Fire, tblMailList_1.mail_Comp_Jewelry, tblMailList_1.mail_Comp_Ceramic, 
                                                   tblMailList_1.mail_Interest
                            FROM          dbo.tblItem AS tblItem_1 INNER JOIN
                                                   dbo.tblBidder AS tblBidder_1 ON tblItem_1.item_bidder_number = tblBidder_1.bidder_number AND 
                                                   tblItem_1.item_sale_id = tblBidder_1.bidder_sale_id INNER JOIN
                                                   dbo.tblMailList AS tblMailList_1 ON tblBidder_1.bidder_mail_id = tblMailList_1.mail_ID
                            WHERE      (tblMailList_1.mail_Comp_Art <> '1' OR
                                                   tblMailList_1.mail_Comp_Art IS NULL) AND (tblMailList_1.mail_Comp_IndArt <> '1' OR
                                                   tblMailList_1.mail_Comp_IndArt IS NULL) AND (tblMailList_1.mail_Comp_GenAm <> '1' OR
                                                   tblMailList_1.mail_Comp_GenAm IS NULL) AND (tblMailList_1.mail_Comp_Fire <> '1' OR
                                                   tblMailList_1.mail_Comp_Fire IS NULL)
                            GROUP BY tblMailList_1.mail_Company, tblMailList_1.mail_Institution, tblMailList_1.mail_LastName, tblMailList_1.mail_FirstName, 
                                                   tblMailList_1.mail_NameTitle, tblMailList_1.mail_ID, tblMailList_1.mail_Comp_Art, tblMailList_1.mail_Comp_IndArt, 
                                                   tblMailList_1.mail_Comp_GenAm, tblMailList_1.mail_Comp_Fire, tblMailList_1.mail_Interest, tblMailList_1.mail_Comp_Jewelry, 
                                                   tblMailList_1.mail_Comp_Ceramic
                            ORDER BY Expr7 DESC) AS tblLimiter ON tblLimiter.Expr1 > 0
WHERE     (tblMailList.mail_Comp_Art <> '1' OR
                      tblMailList.mail_Comp_Art IS NULL) AND (tblMailList.mail_Comp_IndArt <> '1' OR
                      tblMailList.mail_Comp_IndArt IS NULL) AND (tblMailList.mail_Comp_GenAm <> '1' OR
                      tblMailList.mail_Comp_GenAm IS NULL) AND (tblMailList.mail_Comp_Fire <> '1' OR
                      tblMailList.mail_Comp_Fire IS NULL) AND (NOT (tblMailList.mail_ID = tblLimiter.Expr1))
GROUP BY tblMailList.mail_Company, tblMailList.mail_Institution, tblMailList.mail_LastName, tblMailList.mail_FirstName, tblMailList.mail_NameTitle, 
                      tblMailList.mail_ID, tblMailList.mail_Comp_Art, tblMailList.mail_Comp_IndArt, tblMailList.mail_Comp_GenAm, tblMailList.mail_Comp_Fire, 
                      tblMailList.mail_Interest, tblMailList.mail_Comp_Jewelry, tblMailList.mail_Comp_Ceramic
ORDER BY Expr7 DESC

但是,这与另一种方式(返回结果的方式)完全相同。

我真的希望我可以做一个“ AND NOT IN (sub query) ”,因为我可以使这些工作毫无问题。 但是由于Expr7中的SUM,我无法做到这一点。 我是一个MySQL专家,所以我对SQL并不了解很多。 我希望我能提供足够的信息。 如果没有,请告诉我。 感谢您的所有回复。

代替使用TOP 50进行分页,请使用ROW_NUMBER ,然后使用where

WITH CTE AS (
SELECT     
           ROW_NUMBER() OVER (ORDER BY  SUM(dbo.tblItem.item_pr + dbo.tblItem.item_premium) ) RN,
           dbo.tblMailList.mail_ID AS Expr1, dbo.tblMailList.mail_NameTitle AS Expr2, dbo.tblMailList.mail_FirstName AS Expr3, 
           dbo.tblMailList.mail_LastName AS Expr4, dbo.tblMailList.mail_Company AS Expr5, dbo.tblMailList.mail_Institution AS Expr6, 
           SUM(dbo.tblItem.item_pr + dbo.tblItem.item_premium) AS Expr7, 
           dbo.tblMailList.mail_Comp_Art, dbo.tblMailList.mail_Comp_IndArt, 
           dbo.tblMailList.mail_Comp_GenAm, dbo.tblMailList.mail_Comp_Fire, dbo.tblMailList.mail_Comp_Jewelry, dbo.tblMailList.mail_Comp_Ceramic, 
 .....
)
SELECT * FROM CTE WHERE rn Between 50 and 100

暂无
暂无

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

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