Sum of two queries - mysql

My table looks like this:
I made two queries:
SELECT COUNT(column_1) AS result_1 FROM table WHERE column_1= 5;
SELECT COUNT(column_2) AS result_2 FROM table WHERE column_2 = 5;
The first query gives me result_1 = 2, and the second result_2 = 3
I need to make a query that will give me the sum of these two (2+3=5).
I always get two results or just one of them.

Each of these expressions:
column_1 = 5
and
column_2 = 5
evaluates to 0 or 1 (false or true).
So you can use them like this:
SELECT SUM(column_1 = 5) + SUM(column_2 = 5) AS result FROM table
See the demo.
Result:
| result |
| ------ |
| 5 |

You can use subqueries:
SELECT sub1.result_1 + sub2.result_2 FROM (
SELECT COUNT(column_1) AS result_1 FROM table WHERE column_1 = 5) as sub1, (
SELECT COUNT(column_2) AS result_2 FROM table WHERE column_2 = 5) as sub2

Related

MySQL - select product_id from 2 different tables and group results

situation:
table 1 - #__virtuemart_products
virtuemart_product_id | product_special
PRODUCTS_IDS | 0 or 1
table 2 - #__virtuemart_product_badges
virtuemart_product_id | product_badge
PRODUCTS_IDS | for this situation code 3
I have a default SQL
SELECT p.`virtuemart_product_id`
FROM `#__virtuemart_products` as p
WHERE p.`product_special` = 1;
results is product IDs like 2,3,225,...
I need modify this SQL syntax for select IDs from 2 different tables and return one column.
If I modify syntax like that:
SELECT p.`virtuemart_product_id`, badges_table.`virtuemart_product_id`
FROM `#__virtuemart_products` as p, `#__virtuemart_product_badges` as badges_table
WHERE p.`product_special` = 1 OR badges_table.`badge` = 3
Result is:
virtuemart_product_id | virtuemart_product_id
1 | 123
1 | 321
1 | 231
....
why is first column 1,1,1,...? here must be product_id, no product_special code
I need group this results into one column virtuemart_product_id
What I doing wrong?
I think what you are looking for is UNION of the IDs fetched from two different tables.
SELECT p.`virtuemart_product_id`, badges_table.`virtuemart_product_id`
FROM `#__virtuemart_products` as p, `#__virtuemart_product_badges` as
badges_table
WHERE p.`product_special` = 1 OR badges_table.`badge` = 3
What the above query is doing is, it is performing a join between the two tables with the condition that product_special should be 1 or badge should be 3. Hence, each row from one table will be joined with each row of the other table where the condition will satisfy.
To get IDs from both the tables you can get the results from each table according to condition and then perform a UNION on them. So for example
(SELECT `virtuemart_product_id` FROM `#__virtuemart_products` WHERE
`product_special` = 1)
UNION
(SELECT `virtuemart_product_id` FROM
`#__virtuemart_product_badges` WHERE `badge` = 3)
I hope this helps.

SQL Query, how to select a interval where the next value is current value +1, identifying the next gap and leave everything else untouched?

I'm making a program on java using sql querys and i'd like to update a sequence of ids adding 1 to each, but only in the sequence interval.
Let's say i have a table like this:
1 - a | 2 - b | 3 - c | 5 - e | 6 - f
And i'd like to "push" a's ID and subsequents forward by 1, but only while the difference between one another is still 1. The result would be like this:
2 - a | 3 - b | 4 - c | 5 - e | 6 - f
I know it is possible to do programatically, but is there a way to do this with SQL querys? If not, what would be the best way to do this?
Thanks in advance.
Edit: Found the answer thanks to Thorsten Kettner, my query ended up like this:
update pair set id = id + 1
where id >= 1
and id <
(
select min(id)
from (select * from pair) as gap
where gap.id > 1 and not exists
(
select *
from (select * from pair) as oneless
where oneless.id = gap.id - 1
)
)
order by id desc
If you know where the gap is that you want closed (ID 4 in your case) use this:
update mytable set id = id + 1 where id < 4;
If you don't know where the gap is, find it:
select min(id) - 1
from mytable
where not exists
(
select *
from mytable oneless
where oneless.id = mytable.id - 1
);
We can combine both statments now to do the update:
update mytable set id = id + 1
where id <
(
select min(id) - 1
from mytable
where not exists
(
select *
from mytable oneless
where oneless.id = mytable.id - 1
)
);
Let's call your table Pair and the two columns Key and Value. Your query would be something like this:
update p1
set Key = p1.Key + 1
from Pair as p1
inner join Pair as p2
on p2.Key = p1.Key + 1
PS. I'm assuming your result has a typo because after the update, f should have a value of 7.

Mysql count with case when statement

Consider:
SELECT(count(c.id),
case when(count(c.id) = 0)
then 'loser'
when(count(c.id) BETWEEN 1 AND 4)
then 'almostaloser'
when(count(c.id) >= 5)
then 'notaloser'
end as status,
...
When all is said and done, the query as a whole produces a set of results that look similar to this:
Count | status
--------|-------------
2 | almostaloser //total count is between 2 and 4
--------|-------------
0 | loser // loser because total count = 0
--------|-------------
3 | almostaloser //again, total count between 2 and 4
--------|-------------
What I would like to achieve:
a method to reatain the information from the above table, but add a third column that will give a total count of each status, something like
select count(c.id)
case when(count(c.id) = 0 )
then loser as status AND count how many of the total count does this apply to
results would look similar to:
Count | status |total_of each status |
--------|-------------|---------------------|
2 | almostaloser| 2 |
--------|-------------|---------------------|
0 | loser | 1 |
--------|-------------|---------------------|
3 | almostaloser| 2 |
--------|-------------|----------------------
I've been told this could be achieved using a derived table, but i've not yet been able to get them both, only one or the other.
This can be achieved with this query (you must place your original query as subquery in two places):
SELECT t1.*, t2.total_of_each_status
FROM (
-- put here your query --
) t1
INNER JOIN (
SELECT status, count(*) AS total_of_each_status
FROM (
-- put here your query --
) t2
GROUP BY status
) t2 ON t2.status = t1.status

MySQL how to count from GROUP BY

date | userid | companyid
12.8.14 | 1 | 1
12.8.14 | 2 | 2
12.8.14 | 3 | 1
I had a table like above. It is easy to count how many company 1 from table with normal query.
My question is : if my query is select * from table where companyid = '1' group by date, how can i get mysql_num_row equal to 2 for company 1 and userid is 1 and 3?
select * from table where companyid = '1' group by date will only return me
mysql_num_row equal 1 and result 12.8.14 | 1 | 1
You can nest a query to get the sum of company one entries and then join that nested query to an outer query:
SELECT ABB2.*, ABB1.mysql_num_row
FROM `table` AS ABB2
JOIN
(SELECT companyid, COUNT(userid) AS mysql_num_row
FROM `table`
GROUP BY companyid) AS ABB1 ON ABB1.companyid = ABB2.companyid
WHERE ABB2.companyid = 1;
Example
try like this also
select *,(select count(*) from table1 where companyid=a.companyid) as count
from t as a where companyid=1
You wanted:
select date,companyid,count(*)
from table
where userid = 1
group by date,companyid

MYSQL select from table where field is in the field

UPDATED
id | id_list
1 | 2,3,5,7
2 | 1,4,5,6
3 | 1,4,6,7
4 | 2,3,5,8
5 | 1,2,4,8
6 | 2,3,7,8
7 | 1,3,6,9
8 | 4,5,6,9
9 | 7,8
let's say I'm up to the content of id=1
I wanted to select all the rows where id is in id_list of id=1 PLUS the row where id=1
so the result would be
rows with id = 1,2,3,5,7
How to do this query guys?
You can also use a self join
Using IN()
select * from atable a
join atable b on (a.id = b.id )
where 1 IN (a.id_list) or b.id =1
Fiddle with IN()
Using FIND_IN_SET()
select * from atable a
join atable b on (a.id = b.id )
where FIND_IN_SET('1', a.id_list) or b.id =1
Fiddle with FIND_IN_SET()
Using UNION ALL
select * from atable
where id =1
UNION ALL
select * from atable
where 1 IN (id_list)
Fiddle with UNION ALL
Your database design is broken; id_list should be represented as a join table instead of as a string. However, to solve your immediate problem:
select * from table where id=1
or id_list like '1%'
or id_list like '%,1,%'
or id_list like '%,1'
Adjust as needed for PreparedStatement. You have to provide all three cases because if you just did
or id_list like '%1%'
and id_list contained the value 11, you'd get an incorrect match
Try this (see SQL-Fiddle):
SELECT * FROM tbl
WHERE id = 1
OR INSTR((SELECT id_list FROM tbl WHERE id = '1'), id) > 0;
Tested with MySQL 5.5.30
try this one
select *
from tbl
where id=1
or id_list like '%1%'
This appears to call for a union of two sets. The one set would be the single row whose id matches the specified value:
SELECT
id
FROM
atable
WHERE
id = #id
The other set would be the result of this self-join:
SELECT
item.id
FROM
atable AS item
INNER JOIN
atable AS list
ON
FIND_IN_SET(item.id, list.id_list)
WHERE
list.id = #id
That is, the row with the specified id is matched against every row in the table on the condition that the other row's id is found in the specified row's id_list.
You can try the complete query at SQL Fiddle.
Please note that lists aren't a very good design feature. In your situation, it might be better to use a many-to-many table as suggested by #Othman. Only I would probably use a slightly different query to get the desired output, because his doesn't include the specified row itself:
SELECT
id
FROM
manytomany
WHERE
id = #id
UNION
SELECT
linked_id
FROM
manytomany
WHERE
id = #id
;
While the entries in manytomany are assumed to be unique, the query uses the UNION DISTINCT operator because of the potential duplicates returned by the first subquery, although it is possible to move the application of DISTINCT to the first subquery only like this:
SELECT DISTINCT
id
FROM
manytomany
WHERE
id = #id
UNION ALL
SELECT
linked_id
FROM
manytomany
WHERE
id = #id
;
That first subquery could actually be rewritten simply as SELECT #id AS id, but the rewrite would only make sense if the passed value was guaranteed to be valid, i.e. that it would definitely be found in manytomany.id.
Here's a demo for the other approach too (all three variations, including the SELECT #id AS id one).
I don't have an answer for your question but I encourage you to redesign your table like this I think this called many to many relation
id | friend
1 | 2
1 | 3
1 | 5
1 | 7
2 | 1
2 | 4
2 | 5
2 | 6
3 | 1
3 | 4
3 | 6
3 | 7
And then your query will be like this
SELECT DISTINCT(friend) FROM `new` WHERE id = 1
I am assuming you are using php..
My suggestion is to grab the id_list for id 1.
Explode that id_list on the comma, and then do another mysql query to grab the remaining results for 5|3|6|8
ex) $idarray = explode(",", $result);
select * from your_table where id in ('5','3','6','8')
OPTION 2:
SELECT * FROM your_table
WHERE id = '1'
OR id IN ('\''+(SELECT REPLACE(id_list,',','\',\'') FROM your_table WHERE id = '1')+'\'')
EDIT: Oops, sorry, that should be an OR instead.