MySQL query to limit maximums and minimums - mysql

I have the following table:
INSERT INTO `test_table` (`id`, `x`, `y`) VALUES (1, 0, 10), (2, 6, 10),
(3, 9, 10), (4, 2, 9), (5, 4, 9), (6, 3, 8), (7, 7, 8), (8, 9, 8),
(9, 0, 7), (10, 2, 7), (11, 5, 7), (12, 10, 7), (13, 2, 6), (14, 7, 6),
(15, 0, 5), (16, 4, 5), (17, 9, 5), (18, 1, 4), (19, 3, 4), (20, 5, 4),
(21, 10, 4), (22, 8, 3), (23, 3, 2), (24, 6, 2), (25, 2, 1), (26, 8, 1),
(27, 0, 0), (28, 5, 0), (29, 6, 0), (30, 10, 0);
and it represent the following picture:
The numbers in the red or pink cells represent the "id" and the coordinates for those cells are "x" and "y".
All I have to do is to come up with a query to show all the cells (only the red ones), excluding the 10 cell within the gray square.
So far I have this:
SELECT * FROM `test_table` WHERE
x between 0 and 10 and
x not between 2 and 8 and
y between 0 and 10 and
y not between 2 and 7
order by id ASC
LIMIT 30
Imagining that the grid goes bellow 0 and beyond 10 in both directions (not showing in the picture); the query must have way too many limits. Anyways, the output is not what I want because it only give me the cells in the corners (the ones within the green areas): 1, 3, 8, 27 and 30
another approach will be to subtract this query:
SELECT * FROM `test_table` WHERE
x between 2 and 8 and
y between 2 and 7
order by id ASC
LIMIT 30
from this one:
SELECT * FROM `test_table` WHERE
x between 0 and 10 and
y between 0 and 10
order by id ASC
LIMIT 30
...but once again; i am unable to do it :(

It just needs to exclude x[2:8],y[2,7].
Try this:
SELECT * FROM `test_table`
WHERE NOT(x between 2 and 8 AND y between 2 and 7);

Just to add the other "side" limits; the final query was implemented like this:
SELECT * FROM
`test_table` WHERE
x between 0 and 10 and
y between 0 and 10 and
not
(x between 2 and 8 and
y between 2 and 7)

Related

Sum of values of a field based on another field

I have a table as follows. I need to build a query to find the following.
(Sum of feeComponentValue where feeComponentCalc = 1) - (Sum of feeComponentValue where feeComponentCalc = 1) and it should be group by feeSettingId
Please help
CREATE TABLE `feevalues` (
`feevaluesId` int(11) NOT NULL,
`feeSettingId` int(11) NOT NULL,
`feeComponentId` int(11) NOT NULL,
`feeComponentValue` int(11) DEFAULT NULL,
`feeComponentCalc` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Dumping data for table feevalues
INSERT INTO `feevalues`
(`feevaluesId`, `feeSettingId`, `feeComponentId`, `feeComponentValue`, `feeComponentCalc`)
VALUES
(27, 29, 1, 1000, 1),
(28, 29, 12, 2000, 1),
(29, 29, 3, 3000, 1),
(30, 29, 4, 4000, 1),
(103, 30, 3, 1000, 1),
(104, 30, 1, 2000, 1),
(105, 30, 3, 3000, 1),
(106, 30, 1, 4000, 1),
(107, 30, 14, 5000, 2),
(108, 30, 2, 6000, 2),
(109, 30, 13, 7000, 2),
(110, 30, 2, 8000, 2),
(111, 31, 1, 1000, 1),
(112, 31, 3, 2000, 1),
(113, 31, 13, 4000, 2),
(114, 31, 2, 3000, 2),
(122, 32, 1, 1, 1),
(123, 32, 3, 3, 1),
(124, 32, 4, 4, 1),
(125, 32, 2, 5, 2),
(126, 32, 14, 6, 2),
(127, 32, 13, 7, 2);
--
I assume you mean ...where feeComponentCalc = 2... in the 2nd case, right?
With conditional aggregation:
select
feeSettingId,
sum(case feeComponentCalc when 1 then feeComponentValue else 0 end) -
sum(case feeComponentCalc when 2 then feeComponentValue else 0 end) as result
from feevalues
group by feeSettingId
See the demo.
Or:
select
feeSettingId,
sum(
case feeComponentCalc
when 1 then feeComponentValue
when 2 then -feeComponentValue
else 0
end
) as result
from feevalues
group by feeSettingId
See the demo.
Results:
| feeSettingId | result |
| ------------ | ------ |
| 29 | 10000 |
| 30 | -16000 |
| 31 | -4000 |
| 32 | -10 |

SQL - adding total by searching for another value relating to the amount

been given this problem to solve
Write a function to get the payment sales figures from any given shop. The shop should be searched for by name.
i have this so far
SELECT shopname SUM ( amount ) AS sales
FROM frs_Shop, frs_Payment
WHERE shopname = "shop name"
i have the amount to add up but when i go to compile it adds up every amount in this table
INSERT INTO frs_Payment
(payid, amount, paydatetime, empnin, custid, pstatusid, ptid)
values
(101, "3.99", "2015-10-26 16:26:15", "NIN001", 1, 1, 1),
(95, "15.96", "2015-09-24 16:26:15", "NIN001", 1, 1, 1),
(102, "3.99", "2015-10-11 13:25:31", "NIN003", 2, 1, 1),
(11, "11.97", "2015-06-12 19:37:59", "NIN010", 3, 1, 1),
(7, "11.97", "2015-04-11 12:41:28", "NIN010", 3, 2, 4),
(8, "7.98", "2015-05-05 22:49:02", "NIN010", 3, 1, 1),
(32, "15.96", "2015-07-19 02:26:49", "NIN024", 5, 2, 4),
(83, "7.98", "2015-08-20 16:21:08", "NIN011", 5, 2, 4),
(6, "15.96", "2015-03-04 10:51:03", "NIN027", 6, 2, 4),
(17, "3.99", "2015-10-03 01:06:15", "NIN028", 6, 1, 1),
(39, "11.97", "2015-03-24 20:03:05", "NIN027", 6, 1, 1),
(103, "3.99", "2015-10-27 14:45:11", "NIN009", 7, 1, 1),
(62, "15.96", "2015-10-12 14:23:23", "NIN001", 8, 1, 1),
i want it to only add up the ones i specify with the empnin
You can use an explicit join, and a GROUP BY. I made an assumption on the primary/foreign key relationship between frs_Shop and frs_Payment.
SELECT s.shopname
, p.empnin
, SUM ( p.amount ) AS sales
FROM frs_Shop s
INNER JOIN frs_Payment p on s.empnin = p.empnin
WHERE s.shopname = "shop name"
GROUP BY s.shopname, p.empnin

mysql consult in same table

i have this table
INSERT INTO `relationships` (`id`, `term_id`, `order`) VALUES
(1, 1, 0),
(4, 2, 0),
(4, 3, 0),
(4, 4, 0),
(4, 5, 0),
(4, 7, 0),
(4, 8, 0),
(6, 3, 0),
(6, 8, 0),
(6, 9, 0),
(8, 6, 0),
(8, 7, 0),
(8, 8, 0),
(8, 10, 0),
(15, 3, 0),
(15, 4, 0),
(15, 10, 0);
I need to select all term_id containing the number 8 and 5 (relationship between this numbers)
expected result = id 4 and id 8
I try this
SELECT `id` FROM `relationships` WHERE `term_id`=8 or `term_id`=5
but selects all term_id belong to 8 and 5
result = id 4 id 8 AND id --> 6 <-- This is not the result I want.
This does the job:
SELECT
id
FROM relationships a
WHERE
a.term_id = 5 AND
EXISTS (SELECT * FROM relationships b WHERE b.term_id = 8 AND b.id = a.id) > 0
demo: http://www.sqlfiddle.com/#!9/e78cc/4/0

Mysql Match and count in the same table

I'm having an trouble with count product with some conditions on the same table..
Table structure:
INSERT INTO `filter` (`filter_seq_id`, `group_id`, `product_seq_id`) VALUES
(1, 1, 10),
(2, 1, 11),
(3, 1, 12),
(4, 1, 13),
(5, 2, 14),
(6, 2, 15),
(7, 2, 16),
(8, 2, 17),
(9, 3, 18),
(10, 3, 19),
(11, 3, 20),
(12, 3, 21),
(13, 4, 20),
(14, 4, 11),
(15, 4, 27),
(16, 4, 29),
(17, 5, 11),
(18, 5, 20),
(19, 5, 27),
(20, 5, 13);
Here i want count distinct product_seq_id for the group_id (1,2,3) only if product_seq_id also exits in both (4,5) group id..
for example:
group_id -> 1 found product_seq_id 11 in 4,5 so distinct count is 1
group_id -> 2 found nothing
group_id -> 3 found product_seq_id 20 in 4,5 so distinct count is 1
i have tried below query its not returning has i expect
its counting if product_seq_id exists in any one of (4,5)
And i want to count only if product_seq_id exits on both "4" and "5" group_id
SELECT
`f`.`group_id`, count(distinct f.product_seq_id) as count
FROM
filter f
JOIN
filter ff ON `ff`.`product_seq_id` = `f`.`product_seq_id`
AND `f`.`group_id` IN (1,2,3)
AND `ff`.`group_id` IN (4,5)
GROUP BY `f`.`group_id`
http://sqlfiddle.com/#!2/996c1/1
Is this what you are looking for?
select f123.GROUP_ID, count(f123.PRODUCT_SEQ_ID)
from (select product_seq_id from filter where group_id=4) f4
inner join (select product_seq_id from filter where group_id=5) f5
on f4.product_seq_id = f5.product_seq_id
inner join (select group_id, product_seq_id from filter where group_id<4) f123
on f123.product_seq_id = f5.product_seq_id
group by GROUP_ID order by GROUP_ID
The first two subselects selects all of the product_seq_id which are in filter in the group 4 or 5. Those 2 list are joined together only if both contain the same product_seq_id.
The Result of this is all the product_seq_id which are both in group 4 and group 5 (in this example 11 and 20)
Next this result is joined with the last subselect, which selects all group_id and product_seq_id in the groups 1 to 3. They are only joined if they contain any product_seq_id, which is in the previous result of the other join (so if they contain the product_seq_id 11 or 20). The Result of this looks like this:
Group_ID, Product_Seq_ID
1 11
3 20
This result is then grouped by the Group_ID and the amount of product_seq_id in each group is counted
EDIT: Added Explanation

GROUP BY with only first row of sequence of one column?

at first here is the alpha version of what I want: http://sqlfiddle.com/#!2/45c89/2
However I don't want to count all representative_id, but only this rows with the lowest id, eg:
(`id`, `economy_id`, `representative_id`)
(1, 1, 5), <-this one, lowest id through the same economy_id=1
(2, 1, 6),
(3, 1, 7),
(4, 1, 8),
(5, 1, 3),
(6, 1, 4),
(7, 1, 1),
(8, 1, 2),
(9, 1, 102),
(10, 2, 7), <-this one, lowest id through the same economy_id=2
(11, 2, 8),
(12, 2, 102),
(13, 2, 1),
(14, 2, 2),
(15, 2, 3),
(16, 2, 4),
(17, 3, 3), <-this one, lowest id through the same economy_id=3
(18, 3, 4),
(19, 3, 1),
(20, 3, 2),
(21, 3, 102),
(22, 4, 1), <-this one, lowest id through the same economy_id=4
(23, 4, 2),
(24, 4, 102),
(25, 5, 1), <-this one, lowest id through the same economy_id=5
(26, 5, 2),
(27, 5, 102),
(28, 5, 7),
(29, 6, 1), <-this one, lowest id through the same economy_id=6
The output should be:
representative_id, count()
According to above example:
5, 1
7, 1
3, 1
1, 3
Is it possible only in SQL?
If I'm understanding your question correctly, I think this should work using min in a subquery and joining back to itself:
select s.representative_id, count(*)
from stl_parliament s
join
(
select min(id) minid
from stl_parliament
group by economy_id
) t on s.id = t.minid
group by s.representative_id
Updated Fiddle Demo
SELECT x.representative_id
, COUNT(*) total
FROM stl_parliament x
JOIN
( SELECT economy_id
, MIN(id) min_id
FROM stl_parliament
GROUP
BY economy_id
) y
ON y.economy_id = x.economy_id
AND y.min_id = x.id
GROUP
BY representative_id;
http://sqlfiddle.com/#!2/45c89/34
You question is a bit confusing.
is it what do you want?
http://sqlfiddle.com/#!2/a58c7/19
select count(economy_id), min_rep_id
from
(
SELECT economy_id, min(representative_id) as min_rep_id
from stl_parliament
GROUP BY economy_id
) as x
GROUP BY min_rep_id
A little complex but should work :
select m.col1, m.col2, count(m.col2) from (
select t.economy_id as col1, l.representative_id as col2 from stl_parliament l,
(select economy_id,MIN(id) as minid from stl_parliament GROUP BY economy_id) t
where t.economy_id=l.economy_id and t.minid=l.id) m group by m.col2
Lots of subqueries, I am not so good with joins
Please try the below query.
SELECT a.rep_id,count(a.rep_id)
FROM(Select min(id) as mid,representative_id as rep_id,economy_id
FROM stl_parliament
GROUP BY economy_id) as a
GROUP BY a.rep_id