Reputation: 3208
I have two tables, the first one contains a limit column. The number in this column must be used to limit the number of records received from the second table.
Is it possible to do this in just one query?
Below my tables and DEMO:
# Create table a
CREATE TABLE `a` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`limit` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
# Create table b
CREATE TABLE `b` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`master` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
# Fill table a
INSERT INTO `a` (`id`, `limit`)
VALUES
(1, 3);
# Fill table b
INSERT INTO `b` (`id`, `name`, `master`)
VALUES
(1, 'record 1', 'groupA'),
(2, 'record 2', 'groupB'),
(3, 'record 3', 'groupA'),
(4, 'record 4', 'groupB'),
(5, 'record 5', 'groupC'),
(6, 'record 6', 'groupC'),
(7, 'record 7', 'groupC'),
(8, 'record 8', 'groupA'),
(9, 'record 9', 'groupD'),
(10, 'record 10', 'groupD');
Query I tested:
SELECT b.*
FROM b
JOIN a ON a.id = 1
GROUP BY b.master
LIMIT 3
This selects only 3 records.
But now I want the limit to be read from table a. I tried to limit like this, but that fails:
SELECT b.*
FROM b
JOIN a ON a.id = 1
GROUP BY b.master
LIMIT a.limit
EDIT:
I've updated the question including the group by
statement
Upvotes: 1
Views: 43
Reputation: 72205
You cannot use user-defined MySQL variables or table fields in the LIMIT
clause. What you can do is use a variable to enumerate records of table b
. Then use this variable to apply the limit:
SELECT t.id, t.name
FROM (
SELECT id, name, @rn := @rn + 1 AS rn
FROM b
CROSS JOIN (SELECT @rn := 0) AS v
ORDER BY id) AS t
INNER JOIN a ON a.id = 1 AND t.rn <= a.`limit`;
Edit:
Here's a version that handles groups. It limits the records of b
to those groups having the biggest population:
SELECT b.id, b.name, b.master
FROM b
INNER JOIN (
SELECT master, @rn := @rn + 1 AS rn
FROM b
CROSS JOIN (SELECT @rn := 0) AS v
GROUP BY master
ORDER BY COUNT(*) DESC) AS t ON b.master = t.master
INNER JOIN a ON a.id = 1 AND t.rn <= a.`limit`;
Upvotes: 2