mysql how do I hide lines with specific value - mysql

How can I hide lines with value 0 of 'rechamadas'.
I've tried with 'where' and the result is the same with or without it.
'case when' returns almost the same but with nulls instead of 0s.
I need something like this:
Data NumeroCliente Rechamadas
15/07/21 16481218527 2
17/07/21 16910110913 2
17/07/21 16030926362 1
select
date_format(datahora, '%d/%m/%y') as 'Data',
numerocliente as NumeroCliente,
count(numerocliente) - 1 as Rechamadas
from ligacoes
-- where numerocliente > 1
group by numerocliente
order by datahora
Data NumeroCliente Rechamadas
15/07/21 16481218527 0
17/07/21 16910110913 2
17/07/21 16030926362 0
17/07/21 16200904978 0
21/07/21 16030219377 0
21/07/21 16900314989 2
21/07/21 16090625771 0
22/07/21 16790310530 1
22/07/21 16080429611 0
edit1: My goal is to know how many times each 'NumeroCliente' reappears per date. I've manage to done that with 'count(numerocliente) - 1' cuz the first time it appears doesnt count to what I need. The table 'ligacoes' has tree columns which are 'numerocliente' (an id to each customer), 'datahora' (datetime format) and 'codigooperador' (fk).
thank you for your time!

MySQL (and many other SQL implementations) have a HAVING clause which is an result limitation that is applied after the GROUP BY:
So your query becomes:
select
date_format(datahora, '%d/%m/%y') as 'Data',
numerocliente as NumeroCliente,
count(numerocliente) - 1 as Rechamadas
from ligacoes
where numerocliente > 1
group by numerocliente
HAVING Rechamadas > 0
order by datahora
ref: manual

Related

MySQL Help - Combining 2 MySQL Selects - Result in 1

I have two MySQL statements (see below), I would like to combine them together so if they both result in a 1 then the end result will be 1. I'm not sure how to construct this and was hoping for some help.
select count(*)
from monitor
where name='job_starttime' and value < ( UNIX_TIMESTAMP( ) -600)
select count(*)
from monitor
where name='job_active' and value = 0
So for example I would like when both statements are true to result in a value of 1, if 1 or none are true it results in a 0.

match multiple numbers in sql and get count of all matches in rows

I have 3 rows in sql:
sno ids
1. 5,6,7
2. 6,8
3. 5,7,8
I would like to know how many users have max match of (5,6,7) in them for eg: ,Sno. 2 has 1 and Sno 3 has 2 and so on.Is there a query/way to do that or its not possible?
While I'd highly recommend normalizing your database (i.e. not storing comma delimited strings in a colum), here's one option using case and find_in_set:
select sno,
case when find_in_set(5, ids) then 1 else 0 end +
case when find_in_set(6, ids) then 1 else 0 end +
case when find_in_set(7, ids) then 1 else 0 end cnt
from yourtable
group by sno
SQL Fiddle Demo

Separating/Sorting single column values into several columns using case function

I have two tables that I want to join and split with a case function depending on the values in one of the columns. (I know, sounds weird so let me explain)
It's a process where I run separate batches. Every batch has several samples that are measured in instances of voltage readings in several locations. My two tables looks like this:
Sample Readings
id id
BatchesID SampleID
... voltage
... location
When a batch is run, it takes one sample at a time and for every location (25 locations) it takes about 20 readings of the voltage before moving on to the next one.
I want to look at one batch at a time, and for every Sample.id, I want to gather the AVG(voltage) for all the locations. My table for Readings turns out like:
SampleID location voltage
1 1 5.23
1 1 4.53
... ... ...
1 25 7.89
2 1 4.96
2 1 5.04
... ... ...
2 25 6.09
...
But I want it to look like:
SampleID avg_v_for_1 avg_v_for_2 ... avg_v_for_25
1 4.73 5.24 ... 6.35
2 3.87 4.76 ... 9.32
... ... ... ... ...
200 6.73 3.87 ... 8.23
Basically, what I want to do is for every separate sample, I want to take the average voltage for all the measurements in every location and put in on a single row. What my current syntax looks like is this:
SELECT Readings.SampleID, Sample.BatchesID
(case when location = '1' then AVG(voltage) else 0 end) avg_v_for_1,
(case when location = '2' then AVG(voltage) else 0 end) avg_v_for_2,
...
(case when location = '25' then AVG(voltage) else 0 end) avg_v_for_25
FROM DB.Readings
INNER JOIN Sample
ON Readings.SampleID = Sample.id
WHERE Sample.BatchesID = 'specific_batch_id'
GROUP BY Readings.location, Sample.id;
The problem is that this generates the following table:
SampleID avg_v_for_1 avg_v_for_2 ... avg_v_for_25
1 4.73 0 ... 0
1 0 4.76 ... 0
1 0 0 ... 6.73
2 3.87 0 ... 0
2 0 4.83 ... 0
...
How can I get MySQL to gather ALL the average values for EVERY location on a SINGLE row? I have tried removing the group by location and only group by sampleID but then I only get the values for the first location and everything else becomes 0.
Any help is appreciated, thank you!
I add another answer with explanation how the the query with AVG(case ..when ... then..end) works, and why the version with case ... when ... then AVG(..) end doesn't give expected results.
The first remark: the ANSI SQL standard for group by queries is the following:
SELECT column1, column2, ... column_n, aggregate_function (expression)
FROM tables
WHERE predicates
GROUP BY column1, column2, ... column_n;
where aggregated_function can be a function such a: SUM, MAX, MIN, COUNT, AVG
There are several rules (restrictions) for the GROUP BY CLASUE, see this link for details: http://etutorials.org/SQL/Mastering+Oracle+SQL/Chapter+4.+Group+Operations/4.2+The+GROUP+BY+Clause/
one of them says that:
GROUP BY clause must include all nonaggregate expressions
It means, that all columns in SELECT clause must be listed in the GROUP BY clause,
for example this query:
SELECT col1, col2, AVG( expression )
FROM table
GROUP BY col2
is wrong, because col1 is not listed in the GROUP BY clause, and this query won't work on all databases (Oracle, Postgresql, MS-SQL etc.) - except MySql (why - I'll tell about it later).
The expression within the aggregated function can refer to all columns of the table, regardless of the column is listed in the GROUP BY clause or not.
Because of the above the query:
SELECT Readings.SampleID,
(case when location = '1' then AVG(voltage) else 0 end) avg_v_for_1
....
GROUP BY sampleId
simply won't work on all databases that are compliant with ANSI SQL, this query will give a syntax error because location is out of AVG function, but is not listed in the GROUP BY clause.
The question - why this query works on MySql ?
Because MySql implemented it's own extension to the GROUP BY query, see this link --> http://dev.mysql.com/doc/refman/5.6/en/group-by-extensions.html
In MySql the select list can refer to nonaggregated columns not listed in the GROUP BY clause. Becaue of this extension our query is syntactically correct and runs on MySql, but gives unexpected (unwanted) results, since an order of expression's evaluation is different:
1. it first runs an aggregated (group by) query and evaluates AVG( price ),
2. then evaluates CASE WHEN ... THEN, but for resultset returned by the aggregated query from point 1
The query with the clause AVG( case when ... then ):
1. first calucates the expression CASE-WHEN-THEN for all table rows
2. then runs an aggregated query for resultset returned by #1 and calculates the AVG.
Try:
SELECT Readings.SampleID, Sample.BatchesID
AVG(case when location = '1' then voltage else null end) avg_v_for_1,
AVG(case when location = '2' then voltage else null end) avg_v_for_2,
...
AVG(case when location = '25' then voltage else null end) avg_v_for_25
FROM DB.Readings
........
GROUP BY sample_id
--- EDIT --> use ifnull function to change nulls into 0
SELECT Readings.SampleID, Sample.BatchesID
ifnull( AVG(case when location = '1' then voltage else null end), 0 ) avg_v_for_1,
ifnull( AVG(case when location = '2' then voltage else null end), 0 ) avg_v_for_2,
...
ifnull( AVG(case when location = '25' then voltage else null end), 0 ) avg_v_for_25
FROM DB.Readings
........
GROUP BY sample_id

MySQL LENGTH() > 0 and NOT NULL not getting expected results

Viewing my result set, I see a blank field despite my conditions.
I tried selecting:
SELECT column
FROM table
WHERE LENGTH(column) > 0 AND column IS NOT NULL
i also tried:
WHERE LENGTH(column) <> 0 AND column IS NOT NULL
but, I'm still seeing a blank field.
In my SELECT, I tried checking the contents of the field:
SELECT column, LENGTH(column), HEX(column)
etc...
But, they both come up as 0 and seemingly empty, respectively.
What did I miss here?
SELECT
....
FROM contacts as co
JOIN clients as cl
ON co.contact_client = cl.client_oldid
-- this starts a where clause
WHERE cl.client_status = 2
-- ORDER BY ends a WHERE clause, and goes only for ordering:
order by
cl.client_name
AND LENGTH(co.contact_email) > 0 -- so, order by result of this 0 or 1
AND co.contact_email is not null -- then, order by result of this 0 or 1
AND TRIM(co.contact_EMAIL) <> ' -- then, order by result of this 0 or 1

Understanding GROUP BY clause

SELECT a,b from <table_name> GROUP BY a,b,c.
Is the above a valid sql statement?
Not without a table name it is not. If it had a table name it would be valid, but probably not very useful.
Typically one would use GROUP BY clauses in conjunction with some aggregate function (SUM, COUNT, MAX, MIN, etc.) to derive some values related to the grouped fields.
Yes, that query is legal SQL. Whether it's useful SQL is another matter entirely.
The query
select a , b
from foo
group by a,b,c
Does the following:
groups the rows from the source table into distinct groups, 1 for each unique combination of columns a, b and c.
Each such group is then collapsed into a single row containing the grouping columns and the values of any required aggregate functions required by the query.
The resulting result set is then returned to the caller, tossing any unwanted columns (in this case, column c).
Since one of the grouping columns is discarded, the specified query is not guaranteed to be a set of unique rows. It might well contain duplicates. For instance, if group by came up with these groups to be returned:
A B C
- - -
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
The results set returned by the query would be
A B
- -
0 0
0 0
0 1
0 1
1 0
1 0
1 1
1 1
And so, not necessarily useful.
If you include a table name I guess you're asking if you can group by an unselected element c. Yes you can.
No - You need a table.
SELECT a,b FROM myTable GROUP BY a,b,c
where myTable is the table you are selecting from (which must have columns a,b and c).
No- because you didn't specify a table name. If you had, then yes, it's certainly valid for mysql, not sure about Oracle (which validates GROUPing very differently). But it doesn't make any sense...
a b c
0 0 0
0 0 1
0 1 0
0 1 1
applying the query to the table above will give:
0 0
0 0
0 1
0 1
And I don't see how that would be a meaningful result - if you don't want an aggregate value, then DISTINCT makes more sense - but gives a different result:
SELECT DISTINCT a, FROM `atable`
0 0
0 1
Maybe if you explained the real reason youwere asking the question we could make a more sensible attempt at answering it.