MySQL subselect needed - mysql

I just can't figure this out. I need a select statement that will find all job_id's where its profile_sent column is ALL non-zero. So in this case the select should return just "2064056592" because all its rows for profile_sent are non-zero, but 4064056590 still has a 0 in one of its rows so it is not found.
I can obviously get the distinct job_id with:
mysql> Select distinct job_id from Table;
+------------+
| job_id |
+------------+
| 4064056590 |
| 2064056592 |
+------------+
But have no idea how to subselect where each job_id has all its profile_sent column as non-zeros.
See https://snipboard.io/x4UNKc.jpg for the table structure.

Using a subquery to find all the distinct job_ids with profile_sent as 0
and filtering them out should work:
SELECT
DISTINCT t.`job_id`
FROM
test_table t
WHERE t.`job_id` NOT IN
(SELECT DISTINCT
t1.job_id
FROM
test_table t1
WHERE t1.`profile_sent` = 0)
Another approach could be grouping them by their job_id and then checking the sum of profile_sent value is 0;
SELECT t.`job_id` FROM `test_table` t
GROUP BY t.`job_id`
HAVING SUM(t.`profile_sent` = 0)=0

Related

Mysql how to sum and display as single row

I have a vote mysql table and users (user column) can vote y or n. (option column)
My table structure is like below:
| id | option | user | 
| 1 | y | jack | 
| 2 | n | jack | 
| 3 | n | michi| 
| 4 | n | michi| 
What I would like to do is, select distinct user and count option and display it in a single row like below:
| y | n |
| 1 | 2 |
I tried GROUP_CONCAT() and SUM but without luck. Can you please help me to get this sql working?
Thanks.
Group functions like GROUP_CONCAT(), SUM() and COUNT() need a GROUP BY statement to know which rows to combine.
In your query, you want to use COUNT().
Try this:
SELECT `option`, COUNT(DISTINCT `user`) AS users
FROM `table`
GROUP BY `option`
DEMO: http://sqlfiddle.com/#!9/705a9d/3
This will show you one row per option. If you want both options across one row, that's a bit trickier. You'll need to use subqueries for each option.
SELECT (
SELECT COUNT(DISTINCT `user`)
FROM `table`
WHERE `option` = 'y'
) AS y, (
SELECT COUNT(DISTINCT `user`)
FROM `table`
WHERE `option` = 'n'
) AS n
DEMO: http://sqlfiddle.com/#!9/705a9d/4
NOTE: You can use COUNT() without GROUP BY. That will make the query combine all found rows together.

Display 0 instead of blank if no record found in table

i want to display '0' when my query will return no records instead of blank
select count(*) AS count
from
tbl a
where
a.Id in ('45')
group by a.Id;
select count(a.Id) AS count
from tbl a
where a.Id in ('45');
The important bit is remove GROUP BY.
But it would be better to restrict counting to one field
This will work
SELECT COUNT(*) as count FROM (
SELECT *
FROM
tbl a
WHERE
a.Id IN ('45')
GROUP BY a.Id) X;
I guess your query should be like this:
select ifnull(count(*), 0) AS count
from
tbl a
where
a.Id in ('45')
group by a.Id;
See the sample attached how you can do this:
mysql> select ifnull(count(*), 0) as counttotal from Persons;
+------------+
| counttotal |
+------------+
| 0 |
+------------+
1 row in set (0.00 sec)

Query won't return results when 0 is returned

I need this query to return results when the count is 0 instead of just producing an empty set. How can I adjust my query so that it produces the following table with a '0' for the count and the appropriate date?
mysql> select count(test.id), date(insert_datetime) date
from db.table test where date(insert_datetime)='2015-08-17'
group by date(insert_datetime);
+--------------+------------+
| count(test.id) | date |
+--------------+------------+
| 42 | 2015-08-17 |
+--------------+------------+
1 row in set (0.14 sec)
mysql> select count(test.id), date(insert_datetime) date
from db.table test where date(insert_datetime)='2015-08-16'
group by date(insert_datetime);
Empty set (0.00 sec)
This should do it:
SELECT theDate AS `date`, IFNULL(subC.theCount, 0) AS `theCount`
FROM (SELECT DATE(20150817) AS `theDate`) AS subD
LEFT JOIN (
SELECT COUNT(test.id) AS theCount, DATE(insert_datetime) AS `theDate`
FROM db.table AS test
WHERE insert_datetime BETWEEN 20150817000000 AND 20150817235959
GROUP BY theDate
) AS subC
USING (theDate)
;
As another user hinted in a now deleted comment: if you are going to need this for a date range, an "all dates" table may come in more handy than the subD subquery; making a SELECT DATE(X) UNION SELECT DATE(Y) UNION SELECT DATE(Z) UNION SELECT DATE(etc...) subquery gets ridiculous fairly quickly.

How to get counts using the `IN` operator

I am trying to use the IN operator to get the count of certain fields in the table.
This is my query:
SELECT order_id, COUNT(*)
FROM remake_error_type
WHERE order_id IN (1, 2, 100)
GROUP BY order_id;
My current output:
| order_id | COUNT(*) |
+----------+----------+
| 1 | 8 |
| 2 | 8 |
My expected output:
| order_id | COUNT(*) |
+----------+----------+
| 1 | 8 |
| 2 | 8 |
| 100 | 0 |
You can write your query this way:
SELECT t.id, COUNT(remake_error_type.order_id)
FROM
(SELECT 1 AS id UNION ALL SELECT 2 UNION ALL SELECT 100) as t
LEFT JOIN remake_error_type
ON t.id = remake_error_type.order_id
GROUP BY
t.id
a LEFT JOIN will return all rows from the subquery on the left, and the COUNT(remake_error_type.order_id) will count all values where the join succeeds.
You can create a temporary table, insert as many order_ids as required, and perform the left join to remake_error_type. At a small number of orders the other answers are sufficient, but if you were doing this for a lot of orders, UNION ALL and sub-queries are inefficient, both to type it up and to execute on the server.
Additionally, this is a very dynamic approach, because you can control easily the values in your temp table by modifying the insert statement.
However, this will only work if the database user has sufficient privileges: at least select, create temporary and drop table.
DROP TABLE IF EXISTS myTempOrders;
CREATE TEMPORARY TABLE myTempOrders (order_id INTEGER, PRIMARY KEY(order_id));
INSERT INTO myTempOrders (order_id) VALUES (1), (2), (100);
SELECT temp.order_id, count(*)
FROM myTempOrders temp
LEFT JOIN remake_error_type ON temp.order_id = remake_error_type.order_id
GROUP BY 1
If the order_id values exist in some table, then it is possible to extract the desired result without creating a temporary table and inserting values into it.
To qualify, the table must
have an auto increment primary key with # rows greater than the maximum sought order_id value
have a starting increment value less than the minimum sought order_id value
have no missing values in the primary key (i.e. no records have been deleted)
if a qualified table exists, then you can run the following query, where you have to replace surrogate with the qualified table name and surrogate_id with the auto-incrementing primary key of the qualified table name
SELECT surrogate.surrogate_id, count(*)
FROM my_qualified_table surrogate
LEFT JOIN remake_error_type ON surrogate.surrogate_id = remake_error_type.order_id
WHERE surrogate.surrogate_id IN (1, 2, 100)
GROUP BY 1
You could use a union for this. No, this does not use the IN operator, but it is an alternative that will give you your expected results. One option is to hardcode the order_id and use conditional aggregation to get the SUM() of rows with that id:
SELECT 1 AS order_id, SUM(order_id = 1) AS numOrders FROM myTable
UNION ALL
SELECT 2 AS order_id, SUM(order_id = 2) AS numOrders FROM myTable
UNION ALL
SELECT 100 AS order_id, SUM(order_id = 100) AS numOrders FROM myTable;
Here is an SQL Fiddle example.

Get mysql result and count specific field

I have database result like this
ID | NAME | TYPE
--------------------
1 | baseball | 1
2 | kickball | 1
3 | football | 1
4 | soccer | 2
How do I do a select * so get all results but also get a total count of type = 2 in the results?
Any help appreciated.
This will give you the type count for the current row's type in each row:
select t1.*, t2.TypeCount
from Table1 t1
inner join (
select TYPE, count(*) as TypeCount
from Table1
group by TYPE
) t2 on t1.TYPE = t2.TYPE
Typically we manage to get this by the way of two distinct results set. However it is possible to get them all in one with a query similar to the following
SELECT ID, Name, Type
FROM MyTable
UNION
SELECT -1, Type, COUNT(*)
FROM MyTable
WHERE Type = 2
GROUP BY Type
ORDER BY ID
The assumption is that all normal IDs are > 0 allowing to the the -1 as a marker for the row with the count. This row will be first in the resultset, thanks to the ORDER BY.
Note that we could complicate things a bit and get a count for all types (or for several), by simply removing (or changing) the WHERE clause in the second query.