I want to count the distinct occurrences of some column grouped and non-grouped by two boolean columns
select count(Distinct some_column) as Uniques, sum(some_other_col)
from myTable T
where T.created_at>'2016-09-15'
group by T.col1, T.col2
This query gives four values
uniques when col1=true and col2=true
uniques when col1=true and col2=false
uniques when col1=false and col2=true
uniques when col1=false and col2=false
Is it possible to change the same query and to get these three values?
I can't get that info combining the first 4 values
uniques (all)
uniques when col1=true
uniques when col2=true
UPDATE
Actually I want to keep the group by because there are some other values that I get the sum.
Use conditional aggregation:
select count(Distinct some_column) as Uniques,
count(distinct case when t.col1 then some_column end) as Uniques_col1_true,
count(distinct case when t.col2 then some_column end) as Uniques_col2_true
from myTable t
where t.created_at > '2016-09-15';
Try this
SELECT SUM(CASE WHEN col1 = TRUE
AND col2 = TRUE THEN 1 ELSE 0 END) AS opt1,
SUM(CASE WHEN col1 = TRUE
AND col2 = FALSE THEN 1 ELSE 0 END) AS opt2,
FROM
(SELECT DISTINCT col1,
col2,
somecolumn
FROM TABLE T
WHERE ...) AS TB
Related
I have this two MySQL statements from same table :
SELECT
`table1`.`product_id` As product_id,
COUNT(DISTINCT(table1.user_id)) AS NonebuyersNumber
FROM table1
WHERE status = 1 AND `ispaid` != 2
GROUP BY `table1`.`product_id`
The second statement is :
SELECT l
`table1`.`product_id` As product_id,
COUNT(DISTINCT(table1.user_id)) AS BuyersNumber
FROM table1
WHERE `ispaid` = 1
GROUP BY `table1`.`product_id`
The result that I want is a table like this one :
I tried to use Union but doesn't work because I have two different columns
Any idea how I can get this 3rd table?
Use conditional aggregation:
SELECT
product_id,
COUNT(DISTINCT CASE WHEN status = 1 AND ispaid != 2
THEN user_id ELSE NULL END) AS NonebuyersNumber
COUNT(DISTINCT CASE WHEN ispaid = 1 THEN user_id ELSE NULL END) AS BuyersNumber
FROM table1
WHERE
(status = 1 AND ispaid != 2) OR
ispaid = 1
GROUP BY
product_id;
This should work because both of your queries aggregate over the product_id and the only differences are the WHERE clauses. We can combine the records from both queries and then use CASE expressions to target records intended for each original query.
SELECT t1.product_id AS product_id
SELECT CASE WHEN t1.NonebuyersNumber IS NULL
THEN 0
ELSE t1.NonebuyersNumber
END
AS NonebuyersNumber,
SELECT CASE WHEN t2.BuyersNumber IS NULL
THEN 0
ELSE t2.BuyersNumber
END
AS BuyersNumber
FROM
(SELECT
`table1`.`product_id` As product_id ,
COUNT(DISTINCT(table1.user_id)) AS NonebuyersNumber
FROM table1 WHERE status =1
AND `ispaid` != 2
GROUP BY `table1`.`product_id`)
AS t1
INNER JOIN
(SELECT
`table1`.`product_id` As product_id ,
COUNT(DISTINCT(table1.user_id)) AS BuyersNumber
FROM table1 WHERE `ispaid` = 1
GROUP BY `table1`.`product_id`)
AS t2
ON t1.product_id = t2.product_id
Basically, you need following
Join both the views on product_id
Use CASE statements in select in case one of the buyers numbers is NULL
I have a query:
SELECT round(addTime/qty, 0) AS col1,
sum(qty) AS col2,
cId AS Id
FROM MyTable
WHERE qty > 0
GROUP BY round(addTime/qty, 0), cId
ORDER BY round(addTime/qty, 0)
But I have to replace addTime with a
SUM(CASE WHEN qty = 1 THEN 1 ELSE DATEDIFF(second,startTime,endTime) END)/qty, 0)
And when I do this:
SELECT round(SUM(case when qty = 1 then 1 else DATEDIFF(second,startTime,endTime) end)/qty, 0) AS col1,
sum(qty) AS col2,
cId
FROM MyTable
WHERE qty > 0
GROUP BY round(SUM(case when qty = 1 then 1 else
DATEDIFF(second,startTime,endTime) end)/qty, 0)/qty, 0), cId
ORDER BY round(SUM(case when qty = 1 then 1 else DATEDIFF(second,startTime,endTime) end)/qty, 0)/qty, 0)
I get
Cannot use an aggregate or a subquery in an expression used for the group by list of a GROUP BY clause.
My idea was that I can use that new query as variable and then use it where I need but then I ran into trouble with MySql syntax.
Big thanks in advance!
SELECT *
FROM (
SELECT
round(SUM(case when qty = 1 then 1 else DATEDIFF(second, startTime,endTime) end)/qty, 0) AS col1,
sum(qty) AS col2,
cId
FROM MyTable
WHERE qty > 0
) AS t
GROUP BY t.col1, t.cId
ORDER BY t.col1
Also I'm not sure, but your DIFFTIME function if different from MySQL DIFFTIME.
Try it with a sub query in the from clause:
Select * from (select round(...) as col1 from MyTable) as tmp where ... Group By tmp.col1
Subqueries in from clause
How to check whether all rows in a table have unique values for a column
having char datatype in a table in MySQL and return the value as yes or no ?
You can try something like this, where ? is the column you want to check :
SELECT IF(t.total = t.total_distinct, 'YES', 'NO') AS result
FROM ( SELECT COUNT(*) AS total
, COUNT(DISTINCT ?) AS total_distinct
FROM tbl
) t
If you ignore NULL values, you can just compare count() and count(distinct):
select (case when count(col) = count(distinct col) then 'All Unique' else 'Duplicates' end)
from table t;
If NULL values are a concern (so NULL would be allowed at most one time), then you can aggregate and look at the maximum count:
select (case when max(cnt) = 1 then 'All Unique' else 'Duplicates' end)
from (select col, count(*) as cnt
from table t
group by col
) col
I would go with the first version of Gordon's answer, but grouped by the Primary key of the table. In other words :
select primary_key_field, (case when count(col) = count(distinct col) then 'All Unique' else 'Duplicates' end)
from table t
group by primary_key_field.
I'm trying to make a statistics page in my php script. in order to select the count from each table I need more than 30 Queries like this
SELECT COUNT(order_id) as `uncompleted_orders` FROM `orders` WHERE `order_status` != 0
and then I need to run another query like this:
SELECT COUNT(order_id) as `completed_orders` FROM `orders` WHERE `order_status` = 1
I've tried this approach, but it didn't work:
SELECT COUNT(order_id) as `uncompleted_orders` FROM `sd_orders` WHERE `order_status` != 4;
SELECT COUNT(order_id) as `completed_orders` FROM `sd_orders` WHERE `order_status` = 4;
Is there any way to creat a new temp table in MySQL contains the count for other tables?
You could try something like this:
SELECT
(
SELECT COUNT(order_id) FROM `sd_orders` WHERE `order_status` != 4
) as `uncompleted_orders`,
(
SELECT COUNT(order_id) FROM `sd_orders` WHERE `order_status` = 4
) as `completed_orders`
You will have a result set with one row and a field for each count.
Without more information it's impossible to generalise, but there are many constructs that can help you here.
First, your example is actually from one table, and not two. This means that you can do the following...
SELECT
COUNT(CASE WHEN order_status = 4 THEN order_id END) AS complete_orders,
COUNT(CASE WHEN order_status <> 4 THEN order_id END) AS incomplete_orders
FROM
sd_orders
This works because COUNT(<something>) doesn't include an NULLs in the results. And by not including an ELSE clause, anything that doesn't match returns NULL. Another way people accomplish the same result is SUM(CASE WHEN ? THEN 1 ELSE 0 END).
Second, where you do actually have multiple tables, you can combine the results in several different ways...
-- Where you want one value from each table...
--------------------------------------------------------------------------------
SELECT
(SELECT COUNT(*) FROM table1 WHERE fieldx = ?) AS value1,
(SELECT COUNT(*) FROM table2 WHERE fieldy = ?) AS value2
-- Where you want one row of values from each table...
--------------------------------------------------------------------------------
SELECT
table1_summary.value1 AS table1_value1,
table1_summary.value2 AS table1_value2,
table2_summary.value1 AS table2_value1,
table2_summary.value2 AS table2_value2
FROM
(
SELECT
COUNT(CASE WHEN fieldx = ? THEN id END) AS value1,
COUNT(CASE WHEN fieldx <> ? THEN id END) AS value2
FROM
table1
)
AS table1_summary
CROSS JOIN
(
SELECT
COUNT(CASE WHEN fieldy = ? THEN id END) AS value1,
COUNT(CASE WHEN fieldy <> ? THEN id END) AS value2
FROM
table2
)
AS table2_summary
-- Where you want many rows, but of the same fields, from each table...
--------------------------------------------------------------------------------
SELECT
*
FROM
(
SELECT
'Table1' AS source_table,
fielda AS some_grouping,
COUNT(CASE WHEN fieldx = ? THEN id END) AS value1,
COUNT(CASE WHEN fieldx <> ? THEN id END) AS value2
FROM
table1
GROUP BY
fielda
UNION ALL
SELECT
'Table2' AS source_table,
fieldb AS some_grouping,
COUNT(CASE WHEN fieldy = ? THEN id END) AS value1,
COUNT(CASE WHEN fieldy <> ? THEN id END) AS value2
FROM
table2
GROUP BY
fieldb
)
AS summary
ORDER BY
source_table,
some_grouping,
value1,
value2
As you can see, there are a lot of ways to do this. How you approach it totally depends on your data and your needs.
Is there a way in mysql to achieve
SELECT COUNT( SUM(field2) ) FROM TABLE WHERE field1='value' GROUP BY field2
Returning one row with the total sum of the counted field 2.
Field 1 && Field 2 are both not unique.
If there is a need for more info , just let me know.
Edit :
I was not thinking clear.
I need the COUNT of The COUNT.
so all the counted values from field 2.
this can be achieved by getting the number of rows , but I chose for this :
SELECT COUNT( first_count ) total_count FROM
( SELECT COUNT( field2 ) as first_count FROM TABLE
WHERE field1='value' GROUP BY field2 )t1
Or is there a faster query?
Cheers !
Your update
SELECT COUNT( first_count ) total_count FROM
(
SELECT COUNT( field2 ) as first_count FROM TABLE
WHERE field1='value' GROUP BY field2 )t1
)
Is a count of the COUNTs for each field2, which is the same as a count of unique field2s;
SELECT COUNT(DISTINCT field2) FROM TABLE WHERE field1='value'
I think you mean:
SELECT field2
, field2 * COUNT(*)
FROM TABLE
WHERE field1 = 'value'
GROUP BY field2
Also:
There is no GROUPED BY. There is: GROUP BY
After your update and clarification, I think what your query shows is the same with:
SELECT COUNT( DISTINCT field2 ) AS total_count
FROM TABLE
WHERE field1 = 'value'