count the numbers of differences in each columns with data reference impossible? - mysql

I need to count the sum of the differences between a set of known data. The equivalent in php is
(count(array_diff_assoc($array1)). Is this possible with Mysql? I have a set of data to compare with each others field column in the table.
my data to compare is columnA : 3, columnB : 6, columnC : 4
the test table is :
ID columnA columnB columnC
1 2 6 1
2 6 1 3
3 3 6 4
result expected :
ID numbersofdifferences
3 0
1 2
2 3
thanks for any help,
Jesisca

This is not necessarily the cleanest but you could use an aggregate function with a CASE expression:
select id,
sum(case when columna = 3 then 0 else 1 end) +
sum(case when columnb = 6 then 0 else 1 end) +
sum(case when columnc = 4 then 0 else 1 end) TotalDiff
from yourtable
group by id;
See SQL Fiddle with Demo.
Edit, this could be done without the aggregate function as well:
select id,
(case when columna = 3 then 0 else 1 end) +
(case when columnb = 6 then 0 else 1 end) +
(case when columnc = 4 then 0 else 1 end) TotalDiff
from yourtable;
See Demo

There isn't a function built in to do something like that, but you could do it manually.
select
id,
case columnA when $columnA then 1 else 0 end +
case columnB when $columnB then 1 else 0 end +
case columnC when $columnC then 1 else 0 end differences
from
myTable
But if you want them in order, you'll want a subselect
select * from
(
select
id,
case columnA when $columnA then 1 else 0 end +
case columnB when $columnB then 1 else 0 end +
case columnC when $columnC then 1 else 0 end differences
from
myTable
) sqlRequiresNameHere
order by differences

Related

Multiple Count with Multiple column

I am new in sql. I want to count something like:
Select count(*) from table where col1= x and col2=x and Col3=x.
I need to count the same value in all different column.
Any help will be appreciated.
You can use conditional aggregation :
Select sum(case when col1='x' then 1 else 0 end) as count_col1,
sum(case when col2='x' then 1 else 0 end) as count_col2,
sum(case when col3='x' then 1 else 0 end) as count_col3
from tab;
If you want to have sum of these count values, consider the above query as an inner and use the following :
Select q.*,
q.count_col1 + q.count_col2 + q.count_col3 whole_sum
from
(
Select sum(case when col1='x' then 1 else 0 end) as count_col1,
sum(case when col2='x' then 1 else 0 end) as count_col2,
sum(case when col3='x' then 1 else 0 end) as count_col3
from tab
) q
Rextester Demo

Distinct Count Query

I have a table below:
Item Status1 Status2
-----------------------------
A Good NULL
A Good NULL
A Good NULL
A Bad Good
B Bad Good
B Good NULL
C Good NULL
C Good NULL
C Good NULL
D Bad Good
Now, I'm thinking off writing a query which gives me the result below:
Item Good Bad
-----------------------------
A 4 1
B 2 1
C 3 0
D 1 1
Distinct in the Item column and the count of Good and Bad for each Item where NULL is not counted.
The column name can be of anything (I just kept it as Good and Bad in my second table).
Any suggestions/ideas on how to achieve my desired results?
Use UNION ALL & do aggregation :
select item, sum(status = 'good'), sum(status = 'bad')
from (select item, status1 as status
from table t
union all
select item, status2
from table t
) t
group by item;
You can use union all and conditional aggregation
select item, count(case when status1='good' then 1 end) as good,
count(case when status1='bad' then 1 end) as bad
from
(
select item , status1 from tablename
union all
select item , status2 from tablename
)A group by item
use union and case when
select Item, sum(case when status = 'good' then 1 else 0 end) as good,
sum ( case when status = 'bad' then 1 else 0 end) as bad
from (select Item, Status1 as status
from table_name
union all
select Item, Status2
from table_name
) t
group by Item;
There's no need for UNION, simply apply some logic.
select Item
,sum(case when Status1 = 'Good' then 1 else 0 end +
case when Status2 = 'Good' then 1 else 0 end) as good
,sum(case when Status1 = 'Bad' then 1 else 0 end +
case when Status2 = 'Bad' then 1 else 0 end) as bad
from tab
group by Item
or
select Item
,count(case when Status1 = 'Good' then 1 end) +
count(case when Status2 = 'Good' then 1 end) as good
,count(case when Status1 = 'Bad' then 1 end) +
count(case when Status2 = 'Bad' then 1 end) as good
from tab
group by Item
You can use sub-query and then apply sum function in outer query
select distinct(item) as item, sum(S1G+S2G) as Good,sum(S1B+S2B) as Bad from ( select item, CASE WHEN status1 ='Good' THEN 1 ELSE 0 END as S1G, CASE WHEN status2 ='Good' THEN 1 ELSE 0 END as S2G, CASE WHEN status2 ='Bad' THEN 1 ELSE 0 END as S2B, CASE WHEN status1 ='Bad' THEN 1 ELSE 0 END as S1B from t1 ) as b group by item
Here is demo

How to select count of different values in the corresponding column in SQL?

I have a table with 3 columns: first one is ID(not important here), second is number, and third is answer. The second and third column data is as follows:
number : answer
1 : yes
1 : yes
1 : no
2 : yes
2 : no
3 : yes
3 : no
3 : no
The output is supposed to be
number - total Yes - total No
1 - 2 - 1
2 - 1 - 1
3 - 1 - 2
i.e. the total number of yes and no for each number. Can someone guide me as to how to write this select query?
SELECT
number,
COUNT(CASE WHEN answer = 'yes' THEN 1 END) AS total_yes,
COUNT(CASE WHEN answer = 'no' THEN 1 END) AS total_no
FROM test_table
GROUP BY number
Here is a SQLFiddle
Assuming you are using sqlite then it will be as follows:
Select Cast(number as varchar) || ' - ' ||
Cast(Sum(case when answer = 'Yes' then 1 else 0 end) as varchar) || ' - ' ||
Cast(SUM(case when answer = 'No' then 1 else 0 end) as varchar)
from table
Group by number
For MySQL it will be:
Select CONCAT_WS(' - ', Cast(number as char),
Cast(Sum(case when answer = 'Yes' then 1 else 0 end) as char),
Cast(SUM(case when answer = 'No' then 1 else 0 end) as char))
from table
Group by number

joining with a group by and pivot

I have two tables as below
tbl1
id qNum
1 1
2 2
3 3
tbl2
id qNum displayNum
1 1 3
2 2 1
3 2 2
4 2 4
Ideally I need a sql results to look like this
qNum display1 display2 display3 display4
1 0 0 1 0
2 1 1 0 1
3 0 0 0 0
I have tried the following sql but this was not correct
SELECT
tbl1.qNum,
CASE when tbl2.displayNum=1 then 1 else 0 end AS filter1,
CASE when tbl2.displayNum=2 then 1 else 0 end AS filter2,
CASE when tbl2.displayNum=3 then 1 else 0 end AS filter3,
CASE when tbl2.displayNum=4 then 1 else 0 end AS filter4,
CASE when tbl2.displayNum=5 then 1 else 0 end AS filter5
FROM
tbl1
Left Join tbl2 ON tbl1.qNum = tbl2.qNum
GROUP BY
tbl1.qNum
Could anyone help a little please!!
You have use MAX function to pivot the table
Try this:
SELECT tbl1.qNum,
MAX(CASE WHEN tbl2.displayNum=1 THEN 1 ELSE 0 END) AS filter1,
MAX(CASE WHEN tbl2.displayNum=2 THEN 1 ELSE 0 END) AS filter2,
MAX(CASE WHEN tbl2.displayNum=3 THEN 1 ELSE 0 END) AS filter3,
MAX(CASE WHEN tbl2.displayNum=4 THEN 1 ELSE 0 END) AS filter4,
MAX(CASE WHEN tbl2.displayNum=5 THEN 1 ELSE 0 END) AS filter5
FROM tbl1
LEFT JOIN tbl2 ON tbl1.qNum = tbl2.qNum
GROUP BY tbl1.qNum
Your query is almost correct, you're just missing an aggregate function:
SELECT
tbl1.qNum,
MAX(CASE when tbl2.displayNum=1 then 1 else 0 end) AS filter1,
MAX(CASE when tbl2.displayNum=2 then 1 else 0 end) AS filter2,
MAX(CASE when tbl2.displayNum=3 then 1 else 0 end) AS filter3,
MAX(CASE when tbl2.displayNum=4 then 1 else 0 end) AS filter4,
MAX(CASE when tbl2.displayNum=5 then 1 else 0 end) AS filter5
FROM
tbl1
Left Join tbl2 ON tbl1.qNum = tbl2.qNum
GROUP BY
tbl1.qNum
The columns you select should always be either in the group by clause or an aggregate function should be applied to them. A group by "collapses" a group of rows and if you don't have an aggregate function on a column (which is not in the group by) a random row of that group is displayed.
Here you can read about the different aggregate functions: GROUP BY (Aggregate) Functions
The MAX() function in our case here returns the greatest value (note: not the row with the greatest value. You can also have a query like this: select min(col), max(col) from whatever).
I just want to point out that in MySQL, you can simplify the expression. It doesn't need a case statement because booleans are treated as integers with values of 0 and 1:
SELECT tbl1.qNum,
MAX(tbl2.displayNum = 1) AS filter1,
MAX(tbl2.displayNum = 2) AS filter2,
MAX(tbl2.displayNum = 3) AS filter3,
MAX(tbl2.displayNum = 4) AS filter4,
MAX(tbl2.displayNum = 5) AS filter5
FROM tbl1 Left Join
tbl2
ON tbl1.qNum = tbl2.qNum
GROUP BY tbl1.qNum;
Normally, I prefer going with ANSI standard syntax. I do, however, find this easier to read than the case syntax.
Also, you may not need tbl1 for the query, if all values you are interested in are already in tbl2.

mysql views my query output i need different manner

This is my query
Select Count(Case When campaign_pid != 0 Then 1 End)
As Email, Count(Case When sms_pid != 0 Then 1 End)
As Sms, Count(Case When survey_pid != 0 Then 1 End)
As Survey From tablename
Please help me This is my query output
Email Sms Survey
21 1 4
i need output like this
name value
Email 21
Sms 1
Survey 4
Please tell me how to get like above optput
Something like the following should work
SELECT 'Email' AS Name, Count(Case When campaign_pid != 0 Then 1 End) As Value From tablename
UNION SELECT 'SMS', Count(Case When sms_pid != 0 Then 1 End)s From tablename
UNION SELECT 'Survey', Count(Case When survey_pid != 0 Then 1 End) From tablename
or better still
SELECT 'Email' AS Name, COUNT() AS Value FROM tablename WHERE campaign_pid <> 0
UNION SELECT 'SMS', COUNT() FROM tablename WHERE sms_pid <> 0
UNION SELECT 'Survey', COUNT() FROM tablename WHERE survey_pid <> 0
Not 100% sure of your additional question, maybe this is what you want
SELECT COUNT(DISTINCT some_unique_col)
FROM table_name
WHERE campaign_pid <> 0
AND sms_pid <> 0
AND survey_pid <> 0
Maybe you want SUM instead of COUNT, if you could provide some sample data and expected results from that it would help