MySQL query for opposite of GROUP BY or DISTINCT? - mysql

I have the answer below that worked fine for me:
now instead of selecting distinct or group by , I want to select all that records ext_no having value zero only.
How to modify this answer? I tried using order by but it's showing an error. Any help will be appreciated. Thanks in advance.
SELECT ext_no, MAX(value)
FROM test
GROUP BY ext_no
HAVING COUNT(*) > 2 AND
COUNT(*) = COUNT(CASE value WHEN 0 THEN 1 END)

There are a couple of ways you can achieve this. Using a couple of correlated subqueries in the WHERE clause or by JOINing to a table containing MAX(value) and COUNT(*) values for each value of ext_no:
Query 1
SELECT ext_no
FROM test t1
WHERE NOT EXISTS (SELECT *
FROM test t2
WHERE t2.ext_no = t1.ext_no AND value != 0)
AND (SELECT COUNT(*)
FROM test t3
WHERE t3.ext_no = t1.ext_no) > 2
The first subquery checks that this ext_no has no value other than 0. The second checks that there are more than 2 copies of this ext_no.
Query 2
In this query we apply all the conditions (no non-zero values of value and more than 2 copies of ext_no) in the JOIN condition.
SELECT t1.ext_no
FROM test t1
JOIN (SELECT ext_no, MAX(value) AS max_value, COUNT(*) AS count
FROM test
GROUP BY ext_no) t2
ON t2.ext_no = t1.ext_no AND t2.max_value = 0 AND t2.count > 2
Output (for both queries)
ext_no
12133
12133
12133
11505
11505
11505
11505
Demo on SQLFiddle

Related

Count number of times that columns A & B contain values that also appear in column B & A

In my database, I have a table with those values :
column_a,column_b
1,2
3,4
2,1
4,3
3,1
5,6
1,4
1,3
I'm able to know how many times there's a match between a specific value, and any other value. Take value "1" :
SELECT COUNT(*) FROM (SELECT * FROM `table` WHERE `column_a` = 1) as T1
JOIN (SELECT * FROM `table` WHERE `column_b` = 1) as T2
WHERE T1.`column_b` = T2.`column_a`
Resultat will be 2, because we have 1,2, 2,1, 1,3 and 3,1 -> 1 matches with 2 and 3.
Now, I want to know the total number of matches. Here, it will be 3 (because there's 3,4 and 4,3).
Does anyone have and idea?
Thank you
One way to solve this is to count all the cases where a matching pair is found but restricting the matches such that only the pair where column_ais greater than column_b is selected to avoid duplication:
SELECT COUNT(*)
FROM `table` t1
WHERE EXISTS (
SELECT *
FROM `table` t2
WHERE t2.column_b = t1.column_a AND t2.column_a = t1.column_b
AND t2.column_a < t1.column_a
)
Output:
3
Demo on SQLFiddle
You can also use least() & greatest() function :
SELECT COUNT(*)
FROM (SELECT COUNT(*)
FROM `table` t1
GROUP BY LEAST(column_a, column_B), GREATEST(column_a, column_B)
HAVING COUNT(*) > 1
) t;
Here is a demo.
Here is one method:
select count(distinct case when a = 1 then b else a end)
from t
where 1 in (a, b);
Here is a db<>fiddle.

How do I find duplicate values across multiple columns in Mysql?

I have a table like this
I want to check the all rows in Column A with column B and get the count of duplicates.
For example, I want to get the
count of 12 as 3(2 times in A+1 time in B)
count of 11 as 2(2 times in A+0 time in B)
count of 13 as 2(1 time in A+0 time in B)
How can I acheive it?
You can calculate the total occurrences from a union all. A where clause can show only the values that occur in the A column:
select nr
, count(*)
from (
select A as nr
from YourTable
union all
select B
from YourTable
) sub
where nr in -- only values that occur at least once in the A column
(
select A
from YourTable
)
group by
nr
having count(*) > 1 -- show only duplicates
You can combine all values in A and B then do the group by.
Then only select those values found in column A.
Select A, count(A) as cnt
From (
Select A
from yourTable
Union All
Select B
from yourTable) t
Where t.A in
(select distinct A from yourTable)
Group by t.A
Order by t.A;
Result:
A cnt
11 2
12 3
13 1
See demo: http://sqlfiddle.com/#!9/9fcfe9/3

Mysql Join query with count table records with same date

Hello i am having two different table with same field created_date (datetime)
now i want records which counts daywise records with joining table i have done for individual counting as below query :
SELECT DATE(created_date), COUNT(*) FROM table1 GROUP BY DAY(created_date)
SELECT DATE(created_date), COUNT(*) FROM table2 GROUP BY DAY(created_date)
and i am getting results for individuals something like this:
RESULT I NEED :
DATE(created_date) count(table1) count(table2)
2016-12-01 10 3
2016-12-02 1 0
2016-12-05 1 0
2016-11-29 1 0
2016-11-30 4 1
Now i just want to join these result WITH INDIVIDUAL VIEW COUNT ACCORDING TO TABLE can anyone please help me out with this profile....
First take a UNION between your two tables, then use conditional aggregation to determine the counts for each of the two tables. Note that I introduce a field called table_name to keep track of data from each of the two tables.
SELECT t.created_date,
SUM(CASE WHEN t.table_name = 'one' THEN 1 ELSE 0 END) AS count_table_one,
SUM(CASE WHEN t.table_name = 'two' THEN 1 ELSE 0 END) AS count_table_two
FROM
(
SELECT DATE(created_date) AS created_date, 'one' AS table_name
FROM table1
UNION ALL
SELECT DATE(created_date), 'two'
FROM table2
) t
GROUP BY t.created_date
I used DATE consistently everywhere to make the query correct.
Try This:
SELECT created_date, sum(countTable1) countTable1,
sum(countTable2) countTable2
FROM (
SELECT DATE(created_date) created_date, COUNT(*) countTable1, NULL countTable2
FROM table1 GROUP BY DAY(created_date)
UNION ALL
SELECT DATE(created_date) created_date, NULL, COUNT(*) countTable2
FROM table2 GROUP BY DAY(created_date)) t GROUP BY t.created_date
You have a problem in your queries, you are grouping by DAY(date) and showing 'date' so the result will be first date with day(date), yet repeating it to avoid misunderstanding :)
select IFNULL(A.cd, B.cd), A.cnt, B.cnt from
(SELECT DAY(created_date) d, DATE(created_date) cd, COUNT(*) cnt
FROM table1 GROUP BY DAY(created_date)) as A
LEFT JOIN
(SELECT DAY(created_date) d, DATE(created_date) cd , COUNT(*) cnt
FROM table2 GROUP BY DAY(created_date)) B ON B.d = A.d
Its not too hard just use union if no need to allow duplicate row else use union all for all(means allow duplicate as well).
SELECT DATE(created_date), COUNT(*) FROM table1 GROUP BY DAY(created_date)
UNION
SELECT DATE(created_date), COUNT(*) FROM table2 GROUP BY DAY(created_date)
SELECT T.create_date,ISNULL(T.count,0)AS Counttable1,ISNULL(X.count,0)AS Counttable2 FROM(SELECT DATE(created_date) AS create_date,COUNT(*) as count FROM table1 GROUP BY DAY(created_date)) AS T LEFTJOIN(SELECT DATE(created_date) AS create_date, COUNT(*) as count FROM table2 GROUP BY DAY(created_date))AS X ON T.create_date=X.create_date
You actually need a SQL UNION. JOIN natuarually eliminate counts becuase the maytch fields. I.e. if you had 2016-12-01 in both table1 andtable2 then a JOIN on created_date would give you a count of 1 instead of a count of 2.
SELECT DATE(total.created_date), COUNT(*)
FROM (
SELECT created_date FROM table1
UNION ALL
SELECT created_date FROM table2) as total
GROUP BY total.created_date
HERE you simply union the two tables since they have a matching column name. Then you get back every date from both tables. That is in the inner query. The outer query then does the counting.
Hope that makes sense.

How can I return rows where only duplicates within a certain column exist?

Suppose that my database looks something like the following:
First Entry | Second Entry | Third Entry
0 0 0
0 1 2
2 1 0
2 0 1
3 0 0
I am trying to return the subset of this table where an element in the FirstEntry column repeats at least once. So in this case it would return all but the final row. How can I go about this? I've tried using things such as count() but have only managed to achieve grouping instead of returning the actual rows I am curious in (in particular, I care aboout Second and Third entry but only when First entry has repeated at least once).
Using IN()
select * from your_table
where FirstEntry in
(
select FirstEntry
from your_table
group by FirstEntry
having count(*) > 1
)
or using a JOIN
select t1.*
from your_table t1
join
(
select FirstEntry
from your_table
group by FirstEntry
having count(*) > 1
) t2 on t1.FirstEntry = t2.FirstEntry
Try this:
select *
from my_table
where First_Entry IN(SELECT First_Entry From my_table
group by First_entry having count(*) > 1)

MySQL select most occurring or average

I have a MySQL table from which I want to select:
1) Either "most occurring" value, if there is any prevailing
2) Or "average" value, if there is no most occurring value.
Example table 1:
value
1
2
3
4
All values are occurred equally, therefore I want to take AVG(`value`)
Example table 2:
value
1
2
2
3
Value 2 prevails, therefore I want to select the value 2.
What mysql query would do this?
Starting from Gordon's answer I tested and corrected the SQL query in SQL Fiddle:
SELECT IF(t4.numcnts = 1, t1.avgvalue, t2.topvalue) AS result
FROM (select avg(value) as avgvalue from test) t1
CROSS JOIN (select value as topvalue from test group by value order by count(*) desc limit 1) t2
CROSS JOIN join (select count(distinct cnt) as numcnts from
(select count(*) as cnt from test group by value) t3) t4
Here is the Fiddle with the two test tables (switch out test2 for test to see the result when a particular value prevails): http://sqlfiddle.com/#!2/76914/3
My changes were to use an IF instead of a CASEstatement in the SELECTclause and to add the necessary table aliases for the subselects.
The following approach calculates both values and then chooses between them:
select (case when numcnts = 1 then avgvalue else topvalue end)
from (select avg(value) as avgvalue from t) cross join
(select value as topvalue from t group by value order by count(*) desc limit 1) cross join
(select count(distinct cnt) as numcnts from (select count(*) as cnt from t group by value))
Note: if you have ties for the top, but other values as well, then an arbitrary value is returned. You don't specify what to do in this case.
Also, the SQL is untested, so it might have syntax errors.