我有一个场景,结果必须受到限制,具体取决于计算另一个表中的 id。
假设我有这两张桌子
counter
和dispanser
,
我想要
select
表中的最后一条记录 counter
并通过计算 dispanser
表中的记录数来限制选择。
类似这样的事情
select * from counter limit (select count(dispID) from dispanser)
更新
ROW_NUMBER()
来计算 counter
中的行数,并仅选择行数小于 dispanser
中值的数量的行:
WITH cte AS (
SELECT *,
ROW_NUMBER() OVER (ORDER BY id) AS rn
FROM counter
)
SELECT id, name
FROM cte
WHERE rn <= (SELECT COUNT(dispID) FROM dispanser)
样本数据的输出(与原始答案相同):
id name
1 sorabh
2 john
3 sorabh
4 john
5 sorabh
上进行演示
原始答案(MySQL 5.7及以下)
如果不使用准备好的语句或存储过程,就无法做到这一点。来自手册:
LIMIT 接受一个或两个数字参数,它们必须都是非负整数常量
在存储过程中,您可以执行类似的操作。
COUNT(dispID)
存储到 cnt 中,然后将该变量用作 LIMIT
的参数。这是上述规则的例外。
DELIMITER //
CREATE PROCEDURE select_counter()
BEGIN
DECLARE cnt INT;
SELECT COUNT(dispID) INTO cnt FROM dispanser;
SELECT * FROM counter LIMIT cnt;
END //
DELIMITER ;
根据评论中的对话,听起来您想要做的是从
counter
中获取 dispanser
中每条记录的计数 - 如果这是错误的,请发表评论,我可以调整我的回复。完成您正在寻找的内容的最佳方法是通过使用 GROUP BY
语法连接子查询。像这样的东西可能会起作用,具体取决于您的架构:
SELECT
d.*,
c.total
FROM
dispanser as d
INNER JOIN (
SELECT
COUNT(*) as 'total',
dispID
FROM
counter
GROUP BY
dispID
) as c
ON c.dispID = d.id
您可以尝试使用动态SQL。
设置变量
@num
以从 dispanser
表中获取金额。
准备好 SQL 语句
CONCAT('select * from counter limit ', @num )
。
最终使用
EXECUTE
动态执行SQL。
SET @sql = CONCAT('select * from counter order by counterID desc limit ', (SELECT count(dispID) from dispanser));
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;