I have entity like this
{
id,
projectId,
name,
age,
address
}
Now I need to return list of users that are connected to projects which have 4 or more users
For example if I have in database records like this
{1, 1, "John", 21, "Address1"}
{2, 1, "Joey", 22, "Address2"}
{3, 2, "Tom", 25, "Address3"}
{4, 3, "Mike", 23, "Address4"}
{5, 1, "John", 26, "Address5"}
{6, 3, "Jane", 28, "Address6"}
{7, 2, "Joe", 23, "Address7"}
{8, 2, "Steve", 24, "Address8"}
{9, 3, "Will", 29, "Address9"}
{10, 1, "Robert", 21, "Address10"}
{11, 2, "James", 20, "Address11"}
i should get returned list
{1, 1, "John", 21, "Address1"}
{2, 1, "Joey", 22, "Address2"}
{3, 2, "Tom", 25, "Address3"}
{5, 1, "John", 26, "Address5"}
{7, 2, "Joe", 23, "Address7"}
{8, 2, "Steve", 24, "Address8"}
{10, 1, "Robert", 21, "Address10"}
{11, 2, "James", 20, "Address11"}
because project with ID 1 have 4 users and also project with ID 2 have 4 users, but project with ID 3 have 3 users and I don't need that users as result.
I'm using SpringData JPA but as I researched JPA doesn't provide option to make such filtering and as other option I found that I can write custom MySql Query but don't know how that query should look like
I've tried something with group by projectId but don't know how to count and get only groups that have 4 or more users
#Query(value = "SELECT * FROM USER u GROUP BY projectId", nativeQuery = true)
List<User> findUsers();
create table temp (
id int,
projectId int,
name varchar(20),
age int,
address varchar(20)
);
insert into temp (id,projectId,name,age,address) values (1, 1, 'John', 21, 'Address1');
insert into temp (id,projectId,name,age,address) values (2, 1, 'Joey', 22, 'Address2');
insert into temp (id,projectId,name,age,address) values (3, 2, 'Tom', 25, 'Address3');
insert into temp (id,projectId,name,age,address) values (4, 3, 'Mike', 23, 'Address4');
insert into temp (id,projectId,name,age,address) values (5, 1, 'John', 26, 'Address5');
insert into temp (id,projectId,name,age,address) values (6, 3, 'Jane', 28, 'Address6');
insert into temp (id,projectId,name,age,address) values (7, 2, 'Joe', 23, 'Address7');
insert into temp (id,projectId,name,age,address) values (8, 2, 'Steve', 24, 'Address8');
insert into temp (id,projectId,name,age,address) values (9, 3, 'Will', 29, 'Address9');
insert into temp (id,projectId,name,age,address) values (10, 1, 'Robert', 21, 'Address10');
insert into temp (id,projectId,name,age,address) values (11, 2, 'James', 20, 'Address11');
QUERY :
SELECT *
FROM temp
WHERE projectid IN (SELECT projectid
FROM temp
GROUP BY projectid
HAVING Count(*) > 3)
I need to find sum of specific columns as per matched some of columns value in database table.
Please check mysql table that i use :
CREATE TABLE IF NOT EXISTS `plant_production_items` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`plant_production_id` int(11) NOT NULL,
`materialid` int(11) NOT NULL,
`packaging_id` int(11) NOT NULL,
`grade_id` int(11) NOT NULL,
`slabs` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `material_purchase_id` (`plant_production_id`),
KEY `grade_id` (`grade_id`),
KEY `packaging_id` (`packaging_id`),
KEY `slabs` (`slabs`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=104 ;
Value are as under :
INSERT INTO `plant_production_items` (`id`, `plant_production_id`, `materialid`, `packaging_id`, `grade_id`, `slabs`) VALUES
(5, 4, 22, 85, 29, 4444),
(6, 5, 22, 14, 25, 3234),
(8, 6, 27, 21, 60, 4444),
(11, 8, 22, 85, 29, 44444),
(19, 7, 22, 84, 29, 434),
(75, 10, 26, 0, 51, 1233),
(76, 10, 24, 17, 34, 251),
(78, 10, 26, 0, 46, 3234),
(91, 9, 27, 21, 57, 1000),
(92, 9, 27, 21, 57, 2000),
(93, 3, 23, 16, 32, 5000),
(94, 3, 27, 21, 54, 3233),
(101, 3, 27, 21, 0, 700),
(103, 3, 29, 27, 0, 6666);
I want total sum of 'slabs' columns as per unique value founded in following column :
plant_production_id
materialid
packaging_id
grade_id
In short we need to find combination of all 4 values of above and need to show total sum of 'slabs' column.
For example :
there are two records which are same:
(91, 9, 27, 21, 57, 1000),
(92, 9, 27, 21, 57, 2000),
so here i want to get total sum i.e 1000+2000 = 3000
Out put should be all columns with total slabs. It is not required we need to match all above 4 columns. Actually we need to find all total slabs as per total records found same with above 4 column.
If still not clear then let me know.
You can use GROUP BY like this:
SELECT
plant_production_id,
materialidm,
packaging_id,
grade_id,
SUM(`slabs`) slabs_sum
FROM plant_production_items
GROUP BY plant_production_id, materialidm, packaging_id, grade_id;
So it gives the sum of the slabs for rows with the same values for columns grouped by.
I have two tables, and I want to update the rows of torrents from scrapes every day.
scrapes:
id, torrent_id, name, status, complete, incomplete, downloaded
1, 1, http://tracker1.com, 1, 542, 23, 542
2, 1, http://tracker2.com, 1, 542, 23, 542
3, 2, http://tracker1.com, 1, 123, 34, 43
4, 2, http://tracker2.com, 1, 123, 34, 43
5, 3, http://tracker1.com, 1, 542, 23, 542
6, 3, http://tracker2.com, 1, 542, 23, 542
7, 4, http://tracker1.com, 1, 123, 34, 43
8, 4, http://tracker2.com, 1, 123, 34, 43
9, 5, http://tracker1.com, 1, 542, 23, 542
10, 5, http://tracker2.com, 1, 542, 23, 542
11, 6, http://tracker1.com, 1, 123, 34, 43
12, 6, http://tracker2.com, 1, 123, 34, 43
torrents:
id, name, complete, incomplete, downloaded
1, CentOS, 0, 0, 0
2, Ubuntu, 0, 0, 0
3, Debian, 0, 0, 0
4, Redhat, 0, 0, 0
5, Fedora, 0, 0, 0
6, Gentoo, 0, 0, 0
The scrapes may have multiple name, but I want to get the values only from the first found (for better performance) and also, I need to update only torrents ids 1, 3, 6 on one query.
UPDATE (SELECT * FROM scrapes WHERE torrent_id IN(1,3,6) GROUP BY torrent_id) as `myview` JOIN torrents ON myview.torrent_id=torrents.id SET torrent.complete=myview.complete WHERE 1
I have a query that tries to find all shopping carts containing a set of given packages.
For each package I join the corresponding cartitem table once, because I am only interested in carts containing all given packages.
When I reach more than 15 packages(joins) the query performance rapidly drops.
I have two indeces on the corresponding foreign columns and am aware that mysql uses only one of them. When I add an index over the 2 columns(cartitem_package_id,cartitem_cart_id) it works, but is this the only way to solve this situation?
I would like to know why MYSQL suddently stucks in this situation and what may be the mysql internal problem, because I do not see any deeper problem with this definition and query? Does that may be an issue with the query optimizer and can I do something(e.g. adding brackets) to support or force a specific query execution? Or has anyone a different approach here, using another query?
The query looks something like this:
SELECT cart_id
FROM cart
INNER JOIN cartitem as c1 ON cart_id=c1.cartitem_cart_id AND c1.cartitem_package_id= 7
INNER JOIN cartitem as c2 ON cart_id=c2.cartitem_cart_id AND c2.cartitem_package_id= 8
INNER JOIN cartitem as c3 ON cart_id=c3.cartitem_cart_id AND c3.cartitem_package_id= 9
INNER JOIN cartitem as c4 ON cart_id=c4.cartitem_cart_id AND c4.cartitem_package_id= 10
INNER JOIN cartitem as c5 ON cart_id=c5.cartitem_cart_id AND c5.cartitem_package_id= 11
INNER JOIN cartitem as c6 ON cart_id=c6.cartitem_cart_id AND c6.cartitem_package_id= 12
INNER JOIN cartitem as c7 ON cart_id=c7.cartitem_cart_id AND c7.cartitem_package_id= 13
INNER JOIN cartitem as c8 ON cart_id=c8.cartitem_cart_id AND c8.cartitem_package_id= 14
INNER JOIN cartitem as c9 ON cart_id=c9.cartitem_cart_id AND c9.cartitem_package_id= 15
INNER JOIN cartitem as c10 ON cart_id=c10.cartitem_cart_id AND c10.cartitem_package_id= 16
INNER JOIN cartitem as c11 ON cart_id=c11.cartitem_cart_id AND c11.cartitem_package_id= 17
INNER JOIN cartitem as c12 ON cart_id=c12.cartitem_cart_id AND c12.cartitem_package_id= 18
INNER JOIN cartitem as c13 ON cart_id=c13.cartitem_cart_id AND c13.cartitem_package_id= 19
INNER JOIN cartitem as c14 ON cart_id=c14.cartitem_cart_id AND c14.cartitem_package_id= 20
INNER JOIN cartitem as c15 ON cart_id=c15.cartitem_cart_id AND c15.cartitem_package_id= 21
INNER JOIN cartitem as c16 ON cart_id=c16.cartitem_cart_id AND c16.cartitem_package_id= 22
INNER JOIN cartitem as c17 ON cart_id=c17.cartitem_cart_id AND c17.cartitem_package_id= 23
Output:
No result.
Consider the following sample structure:
CREATE TABLE IF NOT EXISTS `cart` (
`cart_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`cart_state` smallint(20) DEFAULT NULL,
PRIMARY KEY (`cart_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=80 ;
INSERT INTO `cart` (`cart_id`, `cart_state`) VALUES
(1, 0),(2, 5),(3, 0),(4, 0),(5, 0),(6, 0),(7, 0),(8, 0),(9, 0),(10, 0),(11, 0),(12, 0),(13, 0),(14, 5),(15, 5),(16, 10),(17, 0),(18, 10),(19, 40),(20, 10),(21, 5),(22, 0),(23, 10),(24, 10),(25, 0),(26, 10),(27, 5),(28, 5),(29, 0),(30, 5),(31, 0),(32, 0),(33, 0),(34, 0),(35, 0),(36, 0),(37, 0),(38, 0),(39, 0),(40, 0),(41, 0),(42, 0),(43, 0),(44, 0),(45, 40),(46, 0),(47, 0),(48, 1),(49, 0),(50, 5),(51, 0),(52, 0),(53, 5),(54, 5),(55, 0),(56, 0),(57, 10),(58, 0),(59, 0),(60, 5),(61, 0),(62, 0),(63, 10),(64, 0),(65, 5),(66, 5),(67, 10),(68, 10),(69, 0),(70, 0),(71, 10),(72, 0),(73, 10),(74, 0),(75, 10),(76, 0),(77, 10),(78, 0),(79, 10);
CREATE TABLE IF NOT EXISTS `cartitem` (
`cartitem_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`cartitem_package_id` int(10) unsigned DEFAULT NULL,
`cartitem_cart_id` int(10) unsigned DEFAULT NULL,
`cartitem_price` decimal(7,2) NOT NULL DEFAULT '0.00',
PRIMARY KEY (`cartitem_id`),
KEY `cartitem_package_id` (`cartitem_package_id`),
KEY `cartitem_cart_id` (`cartitem_cart_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=89 ;
INSERT INTO `cartitem` (`cartitem_id`, `cartitem_package_id`, `cartitem_cart_id`, `cartitem_price`) VALUES
(1, 4, 2, 200.00),(2, 7, 3, 30.00),(3, 14, 9, 255.00),(4, 14, 9, 255.00),(5, 22, 9, 120.00),(6, 22, 9, 120.00),(7, 13, 13, 300.00),(8, 13, 13, 300.00),(9, 7, 14, 450.00),(10, 13, 14, 250.00),(11, 17, 14, 150.00),(12, 7, 15, 450.00),(13, 13, 15, 250.00),(14, 18, 15, 127.50),(15, 7, 16, 450.00),(16, 17, 16, 150.00),(17, 7, 18, 450.00),(18, 7, 19, 450.00),(19, 17, 19, 150.00),(20, 21, 19, 25.00),(21, 13, 20, 300.00),(22, 7, 21, 550.00),(23, 19, 21, 105.00),(24, 22, 21, 120.00),(25, 17, 22, 150.00),(26, 7, 23, 550.00),(27, 11, 24, 245.00),(31, 7, 26, 450.00),(32, 21, 26, 25.00),(33, 21, 26, 25.00),(34, 22, 26, 120.00),(35, 23, 26, 120.00),(36, 10, 27, 382.50),(37, 22, 27, 120.00),(38, 13, 27, 250.00),(39, 10, 28, 297.50),(43, 7, 29, 550.00),(41, 20, 28, 82.50),(42, 22, 28, 120.00),(44, 7, 30, 550.00),(46, 22, 30, 120.00),(47, 23, 30, 120.00),(48, 21, 18, 25.00),(49, 21, 19, 25.00),(50, 17, 37, 150.00),(51, 17, 37, 150.00),(52, 21, 37, 25.00),(53, 21, 37, 25.00),(54, 4, 45, 1.20),(55, 6, 45, 0.00),(56, 7, 47, 450.00),(57, 4, 50, 200.00),(58, 13, 52, 250.00),(59, 13, 19, 300.00),(60, 9, 19, 0.00),(61, 17, 53, 150.00),(62, 7, 53, 450.00),(63, 22, 18, 120.00),(64, 7, 16, 450.00),(65, 7, 54, 450.00),(66, 7, 57, 450.00),(67, 17, 57, 150.00),(68, 7, 56, 450.00),(69, 17, 59, 150.00),(70, 7, 60, 450.00),(71, 17, 61, 150.00),(72, 17, 63, 150.00),(73, 21, 65, 25.00),(74, 7, 66, 450.00),(75, 7, 67, 450.00),(76, 11, 68, 385.00),(77, 7, 71, 450.00),(78, 11, 73, 385.00),(79, 13, 73, 300.00),(80, 4, 75, 200.00),(82, 7, 73, 30.00),(83, 18, 73, 127.50),(84, 23, 73, 120.00),(85, 7, 73, 30.00),(86, 10, 77, 382.50),(87, 7, 79, 550.00),(88, 17, 79, 150.00);
The given query was a possible edge case leading to no results in this example.
SELECT cart_id
FROM cart
INNER JOIN cartitem as c1 ON cart_id=c1.cartitem_cart_id AND c1.cartitem_package_id= 7
INNER JOIN cartitem as c3 ON cart_id=c3.cartitem_cart_id AND c3.cartitem_package_id= 9
INNER JOIN cartitem as c4 ON cart_id=c4.cartitem_cart_id AND c4.cartitem_package_id= 13
INNER JOIN cartitem as c5 ON cart_id=c5.cartitem_cart_id AND c5.cartitem_package_id= 17
INNER JOIN cartitem as c6 ON cart_id=c6.cartitem_cart_id AND c6.cartitem_package_id= 21
Output:
cart_id
-------------
19
19
The query should return all carts containing items that are connected to packages(7,9,13,17,21) in this case.
My approach to your problem would be:
SELECT
cart_id
FROM
cart
INNER JOIN
cartitem
ON
cart_id = cartitem_cart_id
WHERE
cartitem_package_id IN (7,9,13,17,21) -- items that got to be in the cart
GROUP BY
cart_id
HAVING
count(distinct cartitem_package_id) = 5 -- number of different packages
;
DEMO with your data
Explanation
The principle is to filter first with the list of the desired values, here your packages. Now count the different packages per cart (GROUP BY cart_id). If this count matches the number of values in your filter list, then every single package must be in this cart.
You can replace the value list of the IN clause with a subselect, if you get those values from a subselect.
You should see that this approach should be easy to adapt to similar needs.
I've got a MySQL innodb table (sqlfiddle demo) with
id, name_id, name, content
And content like
1, NULL, 'Brian', 'Bridge to terabithia'
2, NULL, 'Brian', 'Pulp fiction'
3, NULL, 'Brian', 'Trainspotting'
4, NULL, 'Luke', 'Watchmen'
5, NULL, 'Luke', 'Constantine'
6, NULL, 'Tony', 'Dark knight'
7, NULL, 'Tony', 'Shutter Island'
8, NULL, 'John', 'Machinist'
9, NULL, 'John', 'Matrix'
10, NULL, 'John', 'Sin city'
11, NULL, 'John', 'Mad Max'
The id is unique to each row. But I can't get, how to set auto_increment name_id to each unique name.
Here's (sqlfiddle) what I'm trying to achieve.
1, 1, 'Brian', 'Bridge to terabithia'
2, 1, 'Brian', 'Pulp fiction'
3, 1, 'Brian', 'Trainspotting'
4, 2, 'Luke', 'Watchmen'
5, 2, 'Luke', 'Constantine'
6, 3, 'Tony', 'Dark knight'
7, 3, 'Tony', 'Shutter Island'
8, 4, 'John', 'Machinist'
9, 4, 'John', 'Matrix'
10, 4, 'John', 'Sin city'
11, 4, 'John', 'Mad Max'
Is it possible to do with MySQL only?
Thank you for reading.
The short answer is you can't do this automatically with only auto_increment, and you probably shouldn't either.
If really have reason to do this you would be much better off normalizing your database, creating a "names" table (name_id PK, name) and removing the "name" column from this table. Honestly I'm not sure what you can really gain from doing this in your example, but I imagine it might be an abstraction of the problem.