Coalesce pulling zero as value - mysql

this is driving me crazy!
I have three tables. The first table has a list of all records along with other data (region, dates, etc). The 2nd and 3rd tables have all the hours/cost data, but the 2nd table contains only historical records, and the 3rd table contains newer records. I want my coalesce to try to find a value in the newer records first, but if no record is found, to look in the historic table. For some reason, even though i KNOW there is a value in the historic table, the result of my coalesce is coming in as 0.
Table1
ID Region
1 US
2 US
3 Europe
4 US
5 Europe
6 US
Table2
ID Hours
1 10
2 15
3 20
Table3
ID Hours
4 3
5 7
6 4
So, my statement is written like this:
SELECT
t1.ID,
COALESCE(t3.hours, t2.hours) AS HOURS
FROM table1 t1
LEFT JOIN table2 t2
ON t1.ID=t2.ID
LEFT JOIN table3 t3
ON t1.ID=t3.ID
Now, for some reason, if the value is found in t3 (the newer records) it pulls in the correct value, but if it does not find a value and has to pull in a value from t2, it is pulling in a 0 instead of the actual value. Result looks like this:
ID HOURS
1 0
2 0
3 0
4 3
5 7
6 4
My guess is that it has something to do with the column type in table 2 (I have all column settings as VARCHAR(55), but I can't find any rules around data types in coalesce function about having to use only a certain column type with coalesce.
Appreciate any guidance!
edited to add results for Spencer's inquiry:
ID t2.hours + 0 t2.hours hex(t2.hours) length(t2.hours)
413190 240 240 F0 3

Incorrect joins:
FROM table1 t1
LEFT JOIN table2 t2 ON t1.ID=t2.ID
^
LEFT JOIN table3 t3 ON t1.ID=t2.ID
^
you're joining table 3 using values from table 2

It looks like the evaluation of t2.hours in the COALESCE function is being done in numeric context, and the values stored in the hours column are evaluating to a numeric value of 0.
One quick way to check what numeric that evaluates to is to add a zero, as in the first expression in this query:
SELECT t2.hours + 0
, t2.hours
, HEX(t2.hours)
, LENGTH(t2.hours)
FROM table2 t2
I'm curious what that query shows for one of the rows that's returning a 0 from the COALESCE expression, whether the numeric evaluation is returning 0, and whether there's any leading wonky characters in the column value.

Related

insert from table1 into table2 where time difference in value input on table 1 is greater than 5 minute

EDIT: I probably should have stated im trying to input the beacon data where the next data input of the same beacon is greater than 5 minutes
im having issue's inserting value from table1 into table2 where there is a greater time input difference between data input on table 1 where the beacon matches.
e.g. the data input gap between ID 7 and ID 8 is larger than 5 minutes but the query im using below returns no data
INSERT INTO table
(`beacon`, `zone`, `mac`, `date`, `time`, `id`)
VALUES
("8","GREEN","EE6A6AF29B8E","2018-11-13","16:21:33","1"),
("8","GREEN","EE6A6AF29B8E","2018-11-13","16:21:43","2"),
("8","GREEN","EE6A6AF29B8E","2018-11-13","16:21:53","3"),
("8","GREEN","EE6A6AF29B8E","2018-11-13","16:22:03","4"),
("8","GREEN","EE6A6AF29B8E","2018-11-13","16:22:13","5"),
("8","GREEN","EE6A6AF29B8E","2018-11-13","16:22:32","6"),
("8","GREEN","EE6A6AF29B8E","2018-11-13","16:22:33","7"),
("8","GREEN","EE6A6AF29B8E","2018-11-13","16:30:00","8"),
("8","GREEN","EE6A6AF29B8E","2018-11-13","16:30:33","9"),
("8","GREEN","EE6A6AF29B8E","2018-11-13","16:30:35","10");
the query that inst returning any results im not sure if i have missed a bit or just written it incorrectly
select a.beacon, a.zone, a.mac, a.date from table a
join table b
on b.id = (select min(id) from table where id > a.id)
where TIME_TO_SEC(TIMEDIFF(a.time, b.time)) > 300;
im trying to insert data from 1 mysql into table into another where the data input on table 1 and where the beacons match is greater than 5 minutes between data inputs into database.table1
e.g.
"8","GREEN","EE6A6AF29B8E","2018-11-13","16:21:33","1"),
"8","GREEN","EE6A6AF29B8E","2018-11-13","16:22:33","1"),
"8","GREEN","EE6A6AF29B8E","2018-11-13","16:23:33","1"), (Ref 1)
value 8 stopped being inputted into database
"10","GREEN","EE6A6AF29B8E","2018-11-13","16:21:33","1"),
"10","GREEN","EE6A6AF29B8E","2018-11-13","16:22:33","1"),
"10","GREEN","EE6A6AF29B8E","2018-11-13","16:25:33","1"),
value 8 started inputting into database
"8","GREEN","EE6A6AF29B8E","2018-11-13","16:28:33","1"), (Ref 2)
"8","GREEN","EE6A6AF29B8E","2018-11-13","16:28:33","1"),
the difference between REF 1 and REF 2 is 5 minutes so insert value 8 into data base
only compare the data where the beacon is the same ( beacon being the 1st column)
so even though there is data input less than 5 minutes before Reference 2 because the beacon is different to Reference 2 it doesn't take this string into account.
Can you mimimise your query to this and check.
select a.beacon, a.zone, a.mac, a.date from table a
join table b on b.id<a.id
and TIME_TO_SEC(TIMEDIFF(a.time, b.time)) >300;
Basically you need those rows which are less than table a's row and those that satisfy the condition.

MySQL Subquery in the same table

This is my first question. I've trying to deal with this all week long with no success.
I have the following table
ID F1 F2
1 1 10
2 3 5
3 2 8
4 7 10
5 11 20
6 12 18
7 15 20
Please note that the values of the rows 2,3,4 are between the values of the first row.
Then, rows 6 and 7 are between the values of the row 5
I need to create a query that should bring me only rows 1 and 5.
I have tried many kind of queries with no success.
I was expecting the following query to work (among many others) but it did not.
select OL.F1,OL.F2
from borrar OL,
(select F1,F2
from borrar
) IL
where
OL.F1 >= IL.F1
and OL.F2 <= IL.F2
Any ideas?.
Thanks,
You can do this with a self-join. The thing that makes rows 1 and 5 different from the other rows is that there are no rows in the table where F1 is less than Row 1&5's value for F1 and F2 is greater than Row 1&5's value for F2.
SELECT t1.*
FROM datatable t1
LEFT OUTER JOIN datatable t2
on t2.F1<=t1.F1 and t2.F2>=t1.F2 and t1.id<>t2.id
WHERE t2.ID is NULL
Self joins are always a bit confusing. Each row is combined with all other rows to find if there is some other row that "spans" it (i.e. F1 and F2 are equal to or outside it) but need to exclude the row spanning itself. Use an outer join, and search for NULL's to find the rows that have no matches.
This seems like a homework problem...
But, one thing I noticed is that F2-F1 = 9 in both cases. Perhaps using that in the Where clause will do the trick ;)

How to join two tables without primary key or unique key?

I have two tables named LocalVSDB and TemporaryVSDB. Both tables have the same columns:
LocalVSDB: msisdn,activateDate
TemporaryVSDB: msisdn,activateDate
But both tables also have duplicate rows for MSIDSN
I need to join these two tables. My intended result looks like this:
MSISDN LocalActivateDate TemporaryActivateDate Datediff
60103820251 2013-12-14 2013-10-05 70
601111000254 2013-12-14 2013-10-05 70
601111000254 2013-12-18 2013-09-10 80
But, since there are duplicate MSIDSNs, I am getting duplicate rows when I join. For example there are 6 rows for certain MSISDN in each table so when I am joining I am getting total 36 rows for that MSISDN.
I am joining using the following query:
SELECT t.msisdn,t.activateDate AS VSDB_Activate_Date,
l.activateDate AS Local_Activate_Date,
DATEDIFF(D,l.activateDate,t.activateDate) AS date_Diff
FROM temporaryVSDB2 t
INNER JOIN LocalVSDB l ON t.msisdn = l.msisdn
WHERE t.activateDate > l.activateDate
Please help me how can I get 6 rows for 6 MSISDN?
Thanks in advance.
The problem is:
where t.activateDate > l.activateDate
That means one row in table one can join to all six rows in table two. You either need to change this to an = or just get a single row from the second table based on certain criteria.
SELECT m.MSIDN, m.ActiveDate, t.ActiveDate, DATEDIFF(DAY, m.ActiveDate, t.ActiveDate) Duration
FROM LocalVSDB m
OUTER APPLY
(
SELECT TOP 1 d.MSIDN, d.ActiveDate
FROM TemporaryVSDB d
WHERE d.ActiveDate > m.ActiveDate
ORDER BY d.ActiveDate
) t
This would find the nearest partner record and duration (the last record will have a null partner though)
You can use your own query adding group by clause provided msidn and activateDate produce unique row.
SELECT t.msisdn,t.activateDate AS VSDB_Activate_Date,
l.activateDate AS Local_Activate_Date,
DATEDIFF(D,l.activateDate,t.activateDate) AS date_Diff
FROM temporaryVSDB2 t INNER JOIN LocalVSDB l ON t.msisdn = l.msisdn
WHERE t.activateDate > l.activateDate
group by t.msisdn, t.activateDate

Is it possible to write a query to compare rows to other rows in same table?

I have a table with the following structure. I need to return all rows where the district of the record immediately preceding and immediately following the row are different than the district for that row. Is this possible? I was thinking of a join on the table itself but not sure how to do it.
id | zip_code | district
__________________________
20063 10169 12
20064 10169 9
20065 10169 12
Assuming that "preceding" and "following" are in the sense of the ID column, you can do:
select *
from zip_codes z1
inner join zip_codes z2 on z1.id=z2.id + 1
inner join zip_codes z3 on z1.id=z3.id - 1
where z1.district <> z2.district and z1.district <> z3.district
This will automatically filter out the first and last rows, because of the inner joins, if you need those to count, change it to left outer join.
Also, this checks if it's different from both. To find if it's different from either (as is implied in the comment), change the and in the where clause to an or. But note, that then, all three rows in your example fit that criteria, even if there are long rows of twelves above and below these rows.

Mysql: Counting a matching bulk between two sets of values within multiple tables?

Is there a way to count a bulk set of matching rows between tables using COUNT() AS number_matches?
I was thinking of including some sort of looping method that satifies a searching algorithm, but before I do that I was wondering/hoping for a more simple approach.
TABLE_1
Row 1:
number_1) 1
number_2) 2
number_3) 3
number_4) 4
Row 2:
number_1) 2
number_2) 4
number_3) 5
number_4) 6
compare with
TABLE_2
Row 1:
number_1) 2
number_2) 4
number_3) 6
number_4) 8
RESULT
Row 1:
number_matches) 2
Row 2:
number_matches) 3
Given your example I think you want to count the amount of records of a join, right?
select count(*) from table_1 t1
join table_2 t2 on t1.col = t2.col