How to add value to a subquery? - mysql

I have this simple query:
SELECT DISTINCT images.id
FROM `images`
WHERE `images`.`user_id` IN
(SELECT following_id
FROM `follows`
WHERE `follows`.`follower_id` = 5717
AND `follows`.`accepted` = 1)
ORDER BY id DESC LIMIT 1000
OFFSET 0
I want to append a value to the list of values returned by the subquery. So if the subquery returns:
23
59
14
77
I want it to be:
23
59
14
77
86
(note the extra 86 at the bottom).

If you always want 86 to be added, then just use a UNION ALL on the subquery, this will ensure that 86 is always included in your IN clause subquery:
SELECT DISTINCT spentits.id
FROM `spentits`
WHERE `spentits`.`user_id` IN
(SELECT following_id
FROM `follows`
WHERE `follows`.`follower_id` = 5717
AND `follows`.`accepted` = 1
UNION ALL
SELECT 86)
ORDER BY id DESC LIMIT 1000
OFFSET 0

You could also just add it as a 2nd piece of criteria in your WHERE clause:
SELECT DISTINCT spentits.id
FROM `spentits`
WHERE `spentits`.`user_id` IN
(SELECT following_id
FROM `follows`
WHERE `follows`.`follower_id` = 5717
AND `follows`.`accepted` = 1)
OR `spentits`.`user_id` = 86
ORDER BY id DESC LIMIT 1000
OFFSET 0

Related

just show not repeated value

This is my table
id
c_id
number
3444
34
3377752
3446
35
3473747
3447
35
3532061
3454
37
3379243
3455
38
3464467
3456
38
3377493
I want to create a table which is show me not repeated value in a c_id column (repeat just 1 time). the result should be:
id
c_id
number
3444
34
3377752
3454
37
3379243
GROUP BY c_id, number
HAVING COUNT(cart_id) = 1
i tried this but it shows me repeated value again
SELECT ANY_VALUE(id) id,
c_id,
ANY_VALUE(`number`) `number`
FROM tablename
GROUP BY c_id
HAVING COUNT(*) = 1;
You can do it as follows :
select t.*
from _table t
inner join (
select c_id
from _table
group by c_id
having count(1) = 1
) as s on s.c_id = t.c_id;
Check it here : https://dbfiddle.uk/RlxxQ_05

Column count in a SQL Query

I want to put COUNT(item_id) in this statement:
SELECT * FROM `notifications` WHERE `uid` = '3' AND `seen` = '0' AND id IN (
SELECT MAX(id), COUNT(item_id)
FROM `notifications`
GROUP BY item_id
) ORDER BY id DESC
But This error occurred: Operand should contain 1 column(s).
Table:
[id] [uid] [item_id] [seen]
1 3 69 0
2 3 69 0
3 3 70 0
4 3 69 0
5 3 70 0
6 3 69 0
Expected output: (Order BY id DESC) where 69 is the last record.
[item_id] [num]
69 4
70 2
Given your sample data and expected results, there's no need for a subquery:
select item_id, count(*)
from notifications
group by item_id
where uid = 3 and seen = 0
order by max(id) desc;
Sample Demo
An educated guess says that you want a JOIN:
SELECT n.*, nmax.cnt
FROM notifications n JOIN
(SELECT item_id, MAX(id) as max_id, COUNT(item_id) as cnt
FROM notifications
GROUP BY item_id
) nmax
ON n.item_id = nmax.item_id AND nmax.id = nmax.max_id
WHERE n.uid = 3 AND n.seen = 0 -- removed the single quotes because these are probably numbers
ORDER BY n.id DESC;
It is unclear whether you want the filtering conditions in the subquery as well.

Select rows that were not selected in a previous query

SELECT * FROM table ORDER BY id ASC
Will output the full table:
id name weight
-- ---- ------
1 XXL 450
2 L 20
3 XL 30
4 XXL 875
5 S 2
Ordering by the weight and limiting to 3:
SELECT * FROM table ORDER BY weight DESC LIMIT 3
Will output:
id name weight
-- ---- ------
4 XXL 875
1 XXL 450
3 XL 30
I want to select all the rows that were not selected in the last query, as such:
id name weight
-- ---- ------
2 L 20
5 S 2
SELECT T.* FROM (
SELECT * FROM table ORDER BY weight DESC LIMIT 10 OFFSET 3
) AS T ORDER BY T.id
The inner query order the rows by weight and crop the results starting from the 4th row to the 13th. The outer query order the partial result by id.
I would just do:
select t.*
from t
where id not in (select id from t order by weight desc limit 3);
or:
select t.*
from t left join
(select id from t order by weight desc limit 3) tt
on t.id = tt.id
where tt.id is null;
However, you need to be very careful about what happens when two rows have the same weight. So, I would recommend these two queries:
select id
from t
order by weight desc, id
limit 3
select t.*
from t left join
(select id from t order by weight desc, id limit 3) tt
on t.id = tt.id
where tt.id is null;

MySQL select upto first occurrence of condition matching

Id | Price
----------------
1 | 10
2 | 20
3 | 40
4 | 10
I need to select ids where first occurrence of summation of price is greater than or equal 55 matching from the bottom. At this case --
I will have 4,3,2 ids selected.
Well, this is kinda tricky for MySQL since it doesn't support any window fuctions and becuase you want to include the first occurrence as well. You can try this:
SELECT * FROM (
SELECT t.id,
(SELECT sum(s.price) FROM YourTable s
WHERE s.id <= t.id) as cuml_sum
FROM YourTable t) ss
WHERE ss.cuml_sum < 55
--Will select all the record will the sum < 55
UNION ALL
SELECT * FROM (
SELECT t.id,
(SELECT sum(s.price) FROM YourTable s
WHERE s.id <= t.id) as cuml_sum
FROM YourTable t) tt
WHERE tt.cuml_sum >= 55
ORDER BY tt.cuml_sum
LIMIT 1
--Will select the first record that have sum >= 55

MYSQL - having count(*) without group by

I have a MySQL table
discount_vouchers
------------------
id
email
test_id
My goal is to list all vouchers that appears more than once with a given email and a given test_id from the GROUP BY:
GROUP BY email, test_id
HAVING count(*) >1
How to get read of this group by?
Here is an example:
discount_vouchers
------------------
1 1#test.com 20
2 1#test.com 10
3 1#test.com 20
4 2#test.com 30
I would like to have as a result:
id email test_id count
1 1#test.com 20 2
2 1#test.com 10 1
3 1#test.com 20 2
4 2#test.com 30 2
Try something like the following
SELECT C2, counter from
(SELECT C2, COUNT(*) as counter FROM test.mytable
GROUP BY C2) as aggregation
WHERE counter > 1
Without using group by, you can do something like
SELECT a.* ,
(SELECT count(*) FROM discount_vouchers b
WHERE a.email = b.email AND a.test_id = b.test_id) as count
FROM discount_vouchers a
How about this?
Aggregate using a subquery, and use its results in order to enrich the actual table:
SELECT `discount_vouchers`.*, `counts`.`count`
FROM `discount_vouchers`
INNER JOIN (SELECT `email`, `test_id`, Count(*) AS 'count'
FROM `discount_vouchers`) AS `counts`
ON `discount_vouchers`.`email` = `counts`.`email`
AND `discount_vouchers`.`test_id` = `counts`.`test_id`;