我正在尝试使用具有左连接的查询进行分页。这导致我的计数是行数,而不是产品数量。用来解释我的问题
SELECT * FROM (
SELECT
DENSE_RANK() OVER (order by tmp.prodId, tmp.prodYear) as rnum,
COUNT(*) OVER () AS totalRecords,
tmp.*
FROM (
SELECT
product.*, widget.*
FROM A_PROD product
LEFT JOIN A_WID widget
ON product.prodId = widget.prodId
AND product.prodYear = widget.prodYear
ORDER BY product.prodId ASC ) tmp
)
WHERE rnum BETWEEN 1 and 10
这导致
|rnum|totalRecords|prodId|prodYear|widgetId|
| 1 | 3 | 13 | 2013 | xyz |
| 1 | 3 | 13 | 2013 | abc |
| 1 | 3 | 13 | 2013 | mno |
当我正在寻找的是
|rnum|totalRecords|prodId|prodYear|widgetId|
| 1 | 1 | 13 | 2013 | xyz |
| 1 | 1 | 13 | 2013 | abc |
| 1 | 1 | 13 | 2013 | mno |
这样orm会将它们视为具有不同小部件的相同产品,分页会将其视为输出中的一行,并且“显示X产品中的Y”消息将是正确的。
这可行吗?
答案 0 :(得分:2)
如果我理解正确,你想要计算输出中的prodid(或者是prodid / year对)。如果是,请将逻辑移至外部查询,以便where
影响它。这可能有效:
SELECT count(distinct prodid) over () as totalRecords, t.*
FROM (SELECT DENSE_RANK() OVER (order by tmp.prodId, tmp.prodYear) as rnum,
tmp.*
FROM (SELECT product.*, widget.*
FROM A_PROD product LEFT JOIN
A_WID widget
ON product.prodId = widget.prodId AND product.prodYear = widget.prodYear
) tmp
) t
WHERE rnum BETWEEN 1 and 10
order by prodId ASC;
注意:我不认为子查询中的order by
有效。我把它移到外部查询。
而且,我不知道DB2是否支持count(distinct)
作为窗口/分析函数。如果没有,则有一种解决方法。
编辑:
如果count
中没有明显,则可以将行号返回1的值相加:
SELECT sum(case when rnum = 1 then 1 else 0 end) over () as totalprodyear, t.*
FROM (SELECT DENSE_RANK() OVER (order by tmp.prodId, tmp.prodYear) as rnum,
tmp.*
FROM (SELECT product.*, widget.*
FROM A_PROD product LEFT JOIN
A_WID widget
ON product.prodId = widget.prodId AND product.prodYear = widget.prodYear
) tmp
) t
WHERE rnum BETWEEN 1 and 10
order by prodId ASC;
重要prodyear
。如果您只需要prod
,请仅在row_number()
上添加其他prodid
分区。
答案 1 :(得分:0)
我无法得到戈登·林诺夫的工作答案,但确实给了我一个想法。
SELECT * FROM (
SELECT MAX(rnum) OVER () as totalprodyear, t.*
FROM (SELECT DENSE_RANK() OVER (order by tmp.prodId, tmp.prodYear) as rnum,
tmp.*
FROM (SELECT product.*, widget.*
FROM A_PROD product LEFT JOIN
A_WID widget
ON product.prodId = widget.prodId AND product.prodYear = widget.prodYear
) tmp
) t
)
WHERE rnum BETWEEN 1 and 10
order by prodId ASC;
为我的目的而努力