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

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

Related

mysql how do I hide lines with specific value

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

return row even if all no value found in table mysql

I Have a select where I am trying to return a row even if there is nothing to be found from the select.
Here is the select
select
1 as risk_management,
0 as Borrow,
0 as Interest,
IFNULL(d.symbol,'E') as symbol,
IFNULL(d.Abbreviation,'EUR') as Abbreviation,
IFNULL(sum(round((a.amount_financed - a.amount_invested - a.amount_withdrawn) * i.average_rate / j.average_rate, 2)),0) as LendingOffers,
IFNULL( min(a.Interest),0) as InterestLend,
0 as VolumePerDay,
0 as LatestId,
0 as InterestLatestRealized,
0 as InterestBorrowLow,
IFNULL(max(a.Interest),0) as InterestLendHigh
from market_cap a
where ........more statements here...
But when I run this select I still get nothing returned.
I would like mysql to generate a row that has 0 for numbers and 'E' and 'EUR' if the value is missing, I thought IFNULL works for that after searching other stackoverflow but its not working in my case.
Since I don't have your data I cannot test the query for you, but I can demonstrate you the basic idea.
You need to create a buffer table with your default data as the main subselect of your query. In my example, it is called "dv" as in "default values".
The query which fetches the real values is also a subquery in the from clause. In my example, it is called "rv" as in "real values".
I use a left (outer) join on to join both select statements with a condition which is always true (on 1 = 1).
Therefore, when the query which fetches the real values cannot find any results, we can still use the values in the default table.
select
IFNULL(rv.risk_management, dv.risk_management) as risk_management,
IFNULL(rv.Borrow, dv.Borrow) as Borrow,
IFNULL(rv.Interest, dv.Interest) as Interest,
IFNULL(rv.symbol, dv.symbol) as symbol,
IFNULL(rv.Abbreviation, dv.Abbreviation) as Abbreviation,
IFNULL(rv.LendingOffers, dv.LendingOffers) as LendingOffers,
IFNULL(rv.InterestLend, dv.InterestLend) as InterestLend,
IFNULL(rv.VolumePerDay, dv.VolumePerDay) as VolumePerDay,
IFNULL(rv.LatestId, dv.LatestId) as LatestId,
IFNULL(rv.InterestLatestRealized, dv.InterestLatestRealized) as InterestLatestRealized,
IFNULL(rv.InterestBorrowLow, dv.InterestBorrowLow) as InterestBorrowLow,
IFNULL(rv.InterestLendHigh, dv.InterestLendHigh) as InterestLendHigh
from (
1 as risk_management,
0 as Borrow,
0 as Interest,
'E' as symbol,
'EUR' as Abbreviation
0 as LendingOffers,
0 as InterestLend,
0 as VolumePerDay,
0 as LatestId,
0 as InterestLatestRealized,
0 as InterestBorrowLow,
0 as InterestLendHigh
) as dv
LEFT JOIN (
select
risk_management,
Borrow,
Interest,
d.symbol,
d.Abbreviation,
sum(round((a.amount_financed - a.amount_invested - a.amount_withdrawn) * i.average_rate / j.average_rate, 2)) as LendingOffers,
min(a.Interest) as InterestLend,
VolumePerDay,
LatestId,
InterestLatestRealized,
InterestBorrowLow,
max(a.Interest) as InterestLendHigh
from market_cap a
where ........more statements here...
) AS rv
ON 1 = 1
Good succes and have a nice day Masnad Nihit

Keep the newest one field value until it changes then keeping its newest field value

I have a few tables that have millions of records where a sensor was sending multiple 0 and 1 values and this data was logged to the table even though we only needed it to keep the very first 1 or 0 per each 1 to 0 or 0 to 1 change.
Adjustments have been made so we only now get the 1 and 0 values on each change and not every one second or whatever but I need to cleanup the unnecessary records from the tables.
I've done some research and testing and I'm having trouble figuring out what method to use here to delete the records not needed. I was trying to figure out how to retain the previous value record using variables and also created row numbers but it's not working as I need it to.
I created an SQLFiddle here and tried some logic per the example post MySQL - How To Select Rows Depending on Value in Previous Row (Remove Duplicates in Each Sequence). I keep getting back no results from this and when I tried running it on a large local MySQL table, and I got an error wto I have to increase the MySQL Workbench read query timeout to 600 or it lost connection.
I also found the "MySql - How get value in previous row and value in next row?" post and tried some variations of it and also "How to get next/previous record in MySQL?" and I've come up with total failure getting the expected results.
The Data
The data in the tables has a TimeStr column and a Value column just as in the screen shot and on the SQLFiddle link I posted with a small sample of the data.
Each record will never have the same TimeStr value but I really only need to keep the very first record time wise when the sensor either turned ON or OFF if that clarifies.
I'm not sure if the records will need an incremental row number added to get the expected results since it only has the TimeStr and the Value records otherwise.
My Question
Can anyone help me determine a method that I can use on a couple large tables to delete the records from a table where there are subsequent and duplicate Value values so the tables only has the very first 1 or 0 records where those actually change from a 1 to 0 or 0 to 1?
I will accept an answer that also results in just the records needed—but any that perform fast would be even more greatly appreciated.
I can easily put those into a temp table, drop the original table, and then create and insert the needed records only into the original table.
Expected Results
| TimeStr | Value |
|----------------------|-------|
| 2018-02-13T00:00:00Z | 0 |
| 2018-02-13T00:00:17Z | 1 |
| 2018-02-13T00:00:24Z | 0 |
| 2018-02-13T00:00:28Z | 1 |
Select t.timestr, t.value from (
SELECT s.*, #pv x1, (#pv := s.value) x2
FROM sensor S, (select #pv := -1) x
ORDER BY TimeStr ) t
where t.x1 != t.x2
See http://sqlfiddle.com/#!9/8d0774/122
Try this :
SET #rownum = 0;
SET #rownum_x = 0;
SELECT b.rownum, b.TimeStr, b.Value
FROM
(
SELECT #rownum := #rownum+1 as rownum, TimeStr, Value
FROM sensor
ORDER BY TimeStr
) b
LEFT JOIN (
SELECT #rownum_x := #rownum_x+1 as rownum_x, TimeStr as TimeStr_x, Value as Value_x
FROM sensor
ORDER BY TimeStr
) x ON b.rownum = x.rownum_x + 1
where b.Value <> x.Value_x or x.Value_x is null
order by b.TimeStr
The result I got is
You want the first record for each value when it appears. This suggests variables. Here is one way that only involves sorting and no joining:
select t.*
from (select t.*,
(case when value = #prev_value then value
when (#save_prev := #prev_value) = NULL then NULL
when (#prev_value := value) = NULL then NULL
else #save_prev
end) as prev_value
from (select t.*
from sensor t
order by timestr
) t cross join
(select #prev_value := -1) params
) t
where prev_value <> value;
Notes:
The subquery for ordering only seems to be needed since MySQL 5.7.
The case is just a way to introduce serialized code. When using a variable it should only be used on one expression.
This only requires one sort -- and if you have an index, that doesn't even need to be a sort.
Here is a SQL Fiddle.

Preference for rows where field is different from "x"

I want to query my database so that I don't order by or order by desc but instead seek rows when a given field is different from 0 first and only after get others ordered by if there are no rows with field != "0". What is the best way to accomplish this or even is it possible to do so?
This is supposing the field can have values from -100 to 0 to 100
With example:
Considering LIMIT equals 3 and field in consideration is field1
field1
10
0
-20
-40
Another set:
field1
0
0
-100
50
In the first set, the results extracted will be 10, -20 and -40 (by any order), while in the second set they should be -100, 50 and 0 (any of the zeros, by any order).
First I'd like to check whether there exists != 0 in the database and if true extract those and only after 0's until I fill the LIMIT
something like this?
its not clear AT ALL what you want so I'm only guessing here.
I want to query my database so that I don't order by or order by desc but instead seek rows when a given field is different from 0
seek rows to me means find all rows that are not 0.
only after get others ordered by if there are no rows with field != "0".
to me that means order the rows in a sub query where the field is not 0.
with that in mind maybe this query?
SELECT * FROM table t
WHERE field IN (
SELECT field
from table t
WHERE field <> 0
ORDER BY field
)
without data It's not clear what you want. but i think something like this is what you were asking.. you could also try
SELECT * FROM table t
WHERE field <> 0
ORDER BY field

Comparing 2 Columns in same table

I need to compare 2 columns in a table and give 3 things:
Count of rows checked (Total Rows that were checked)
Count of rows matching (Rows in which the 2 columns matched)
Count of rows different (Rows in which the 2 columns differed)
I've been able to get just rows matching using a join on itself, but I'm unsure how to get the others all at once. The importance of getting all of the information at the same time is because this is a very active table and the data changes with great frequency.
I cannot post the table schema as there is a lot of data in it that is irrelevant to this issue. The columns in question are both int(11) unsigned NOT NULL DEFAULT '0'. For purposes of this, I'll call them mask and mask_alt.
select
count(*) as rows_checked,
sum(col = col2) as rows_matching,
sum(col != col2) as rows_different
from table
Note the elegant use of sum(condition).
This works because in mysql true is 1 and false is 0. Summing these counts the number of times the condition is true. It's much more elegant than case when condition then 1 else 0 end, which is the SQL equivalent of coding if (condition) return true else return false; instead of simply return condition;.
Assuming you mean you want to count the rows where col1 is or is not equal to col2, you can use an aggregate SUM() coupled with CASE:
SELECT
COUNT(*) AS total,
SUM(CASE WHEN col = col2 THEN 1 ELSE 0 END )AS matching,
SUM(CASE WHEN col <> col2 THEN 1 ELSE 0 END) AS non_matching
FROM table
It may be more efficient to get the total COUNT(*) in a subquery though, and use that value to subtract the matching to get the non-matching, if the above is not performant enough.
SELECT
total,
matching,
total - matching AS non_matching
FROM
(
SELECT
COUNT(*) AS total,
SUM(CASE WHEN col = col2 THEN 1 ELSE 0 END )AS matching
FROM table
) sumtbl