I have the following table of call_logs:
+------------+---------------------+------------+-------------+--------------+
| id | datetime | a_number | b_number | nem |
+------------+---------------------+------------+-------------+--------------+
| 1262662410 | 2020-07-17 10:43:57 | 3415529238 | 12642356719 | |
| 1262661229 | 2020-07-17 10:43:48 | 1126751251 | 12641344559 | |
| 1262658679 | 2020-07-17 10:43:28 | 3516807236 | 16199573103 | |
+------------+---------------------+------------+-------------+--------------+
and another table of prefixes:
+---------+-------+-------------------+------+
| prefix | lenght| description | nem |
+---------+-------+-------------------+------+
| 1907 | 4 | ALASKA | ALAS |
| 1684 | 4 | AMERICAN SAMOA | ASAM |
| 1264 | 4 | ANGUILLA | AGLL |
| 1264235 | 7 | ANGUILLA - MOBILE | AGLM |
| 1264469 | 7 | ANGUILLA - MOBILE | AGLM |
| 1264476 | 7 | ANGUILLA - MOBILE | AGLM |
| 1264536 | 7 | ANGUILLA - MOBILE | AGLM |
| 1264537 | 7 | ANGUILLA - MOBILE | AGLM |
| 1264538 | 7 | ANGUILLA - MOBILE | AGLM |
| 1264539 | 7 | ANGUILLA - MOBILE | AGLM |
+---------+-------+-------------------+------+
What MySQL query or precedure do you recommend to update the call_logs.nem field analyzing the prefixes.prefix field that best matches (with the greatest number of digits) with the field call_logs.b_number.
Example:
+------------+---------------------+------------+-------------+--------------+
| id | datetime | a_number | b_number | nem |
+------------+---------------------+------------+-------------+--------------+
| 1262662410 | 2020-07-17 10:43:57 | 3415529238 | 12642356719 | AGLM |
| 1262661229 | 2020-07-17 10:43:48 | 1126751251 | 12641344559 | AGLL |
+------------+---------------------+------------+-------------+--------------+
call_logs is a big table, it would be good to find the most efficient method.
Can anyone help me on this?
Thanks a lot!
CLARIFICATION:
Both fields: b_numberand prefix are VARCHAR type.
What type of UPDATE Query could be done in this case?
You can use not exists. Assuming that number and prefix are of numeric datatypes:
update call_logs c
inner join prefixes p on (c.b_number / p.prefix) % 10 = 0
set c.mem = p.mem
where not exists (
select 1
from prefixes p1
where (c.b_number / p1.prefix) % 10 = 0 and p1.length > p.length
)
Related
i am having some problems creating a query of my project.
I have created a software that cyclically (every minute) interrogates 3 or 4 devices and saves the collected data (people's incoming and outgoing) on a MySQL database.
This is the structure of my table:
```
+----+----------+----------+----------+---------------------+---------+
| id | DeviceId | ValueIn | ValueOut | DateTime | Status |
+----+----------+----------+----------+---------------------+---------+
| 1 | 1 | 00000429 | 00000327 | 2020-02-20 11:59:23 | online |
| 2 | 2 | 00000350 | 00000278 | 2020-02-28 12:54:12 | online |
| 3 | 1 | 00000000 | 00000000 | 2020-01-25 11:12:13 | offline |
| 4 | 2 | 00000300 | 00000200 | 2020-01-10 08:12:54 | online |
| 5 | 2 | 00000330 | 00000250 | 2020-02-01 09:00:54 | online |
| 6 | 1 | 00000400 | 00000300 | 2020-01-24 18:05:54 | online |
| 7 | 3 | 00000600 | 00000700 | 2020-02-10 13:05:54 | online |
| 8 | 3 | 00000000 | 00000000 | 2020-01-03 15:07:21 | offline |
| 9 | 4 | 00000111 | 00000111 | 2020-02-15 17:20:01 | online |
+----+----------+----------+----------+---------------------+---------+
```
My Query should return one row for each month (grouped by month) and each device with the most recent day of the month that have been collected by the software.
The same line should show also the ValueIn and ValueOut of the previous month: I will need it to work out the difference and calculate the monthly inputs/outputs.
What the table should show:
```
+----------+-----------+----------+---------------------+----------+----------+---------------------+
| ValueIn | ValueOut | DeviceId | DateTime | OLD_IN | OLD_OUT | OLD_DateTime |
+----------+-----------+----------+---------------------+----------+----------+---------------------+
| 00000350 | 000000278 | 2 | 2020-02-28 12:54:12 | 00000300 | 00000200 | 2020-01-10 08:12:54 |
| 00000429 | 000000327 | 1 | 2020-02-20 11:59:23 | 00000400 | 00000300 | 2020-01-25 11:12:13 |
| 00000600 | 000000700 | 3 | 2020-02-10 13:05:54 | 00000000 | 00000000 | 2020-01-03 15:07:21 |
| 00000111 | 000000111 | 4 | 2020-02-15 17:20:01 | 00000000 | 00000000 | null |
+----------+-----------+----------+---------------------+----------+----------+---------------------+
```
So, 50 people entered my DeviceId 2 in February and 78 left.
In DeviceId1 incoming: 429 outgoing: 327
Is it possible ??
I did some tests: if I have no < DateTime rows the query returns no results.
This is my starting query.
SELECT
TodayAccess.ValueIn,
TodayAccess.ValueOut,
TodayAccess.DateTime,
devices.Name,
MAX( OldAccess.ValueIn ),
MAX( OldAccess.ValueOut )
FROM peoplecounter AS TodayAccess
INNER JOIN devices ON TodayAccess.DeviceId = devices.Id
RIGHT JOIN peoplecounter AS OldAccess ON TodayAccess.DeviceId = OldAccess.DeviceId
WHERE TodayAccess.Status = 'online'
AND TodayAccess.DateTime BETWEEN '2020-06-01'
AND '2020-08-31'
AND OldAccess.DateTime < '2020-06-01'
GROUP BY TodayAccess.DeviceId, MONTHNAME(TodayAccess.DateTime)
I thank all those who will help me!
I am facing a huge problem with MYSQL.
I have a table called tperson with the following content
+--------------+------------+
| tperson_id | first_name |
+--------------+------------+
| 1 | juan |
| 2 | miguel |
| 3 | Carlos |
| 4 | Diego |
+--------------+------------+
on the second table i have this data
+--------------+------------+------------+
| tperson_id | trans_code | date_added |
+--------------+------------+------------+
| 1 | 2000-01 |2020/03/03 |
| 1 | 2000-02 |2020/03/04 |
| 2 | 1999-05 |2019/12/25 |
| 3 | 1999-06 |2019/12/26 |
| 3 | 1999-07 |2019/12/27 |
+--------------+------------+------------+
Now I want to have this result in mysql
+--------------+------------+------------+------------+
| tperson_id | first_name | trans_code | date_added |
+--------------+------------+------------+------------+
| 1 | juan |2000-02 | 2020/03/04 |
| 2 | miguel |1999-05 | 2019/12/25 |
| 3 | Carlos |1999-07 | 2019/12/27 |
| 4 | Diego | null | null |
+--------------+------------+------------+------------+
what is the right MYsql statement to generation the result I want?
pls anyone help, I keep looking for the answer found nowhere. I am not good in any database.
thank you so much
I'm assuming your 2nd table name is tdate, and data on trans_code and date_added that's being selected is the latest value if there are more than one data from the same tperson_id on table tdate
SELECT tp.tperson_id, tp.first_name, MAX(td.trans_code), MAX(td.date_added)
FROM tperson tp
LEFT JOIN tdate td
ON tp.tperson_id = td.tperson_id
GROUP BY tp.tperson_id
I have question about SELECT FROM WHERE statement, which returns me bad result.
Here is my table called friends:
+----------+-----------+------------+--------+--------+-------+
| lastname | firstname | callprefix | phone | region | zip |
+----------+-----------+------------+--------+--------+-------+
| Lužný | Bob | 602 | 111222 | OL | 79821 |
| Matyáš | Bob | 773 | 123456 | BR | NULL |
| Strouhal | Fido | 300 | 343434 | ZL | 76701 |
| Přikryl | Tom | 581 | 010101 | PL | 72000 |
| Černý | Franta | 777 | 000999 | OL | 79801 |
| Zavadil | Olda | 911 | 111311 | OL | 79604 |
| Berka | Standa | 604 | 111234 | ZL | 72801 |
| Vlcik | BbB | 736 | 555444 | KV | 35210 |
+----------+-----------+------------+--------+--------+-------+
And here is my query.
SELECT * FROM friends WHERE region <= 'z';
I would expect that the rows with region ZL should be present, but they are not. Can you please tell me why?
Result is:
+----------+-----------+------------+--------+--------+-------+
| lastname | firstname | callprefix | phone | region | zip |
+----------+-----------+------------+--------+--------+-------+
| Lužný | Bob | 602 | 111222 | OL | 79821 |
| Matyáš | Bob | 773 | 123456 | BR | NULL |
| Přikryl | Tom | 581 | 010101 | PL | 72000 |
| Černý | Franta | 777 | 000999 | OL | 79801 |
| Zavadil | Olda | 911 | 111311 | OL | 79604 |
| Vlcik | BbB | 736 | 555444 | KV | 35210 |
+----------+-----------+------------+--------+--------+-------+
When I try this query:
SELECT * FROM friends WHERE region >= 'z';
the result contains both rows with region = 'ZL'
????
Thank you!
Because "ZL" is greater than "Z." Z is just one character so will only return values less that Z or with the value of Z. What are you trying to achieve with this query?
Can you please tell me why?
If you add a record where region is Z, and sorted those rows alphabetically by region, would you expect ZL to come before or after Z? Obviously it would come after, so it does not meet your criteria.
If you want to only consider the first character, then add that to your criteria:
SELECT * FROM friends WHERE LEFT(region,1) <= 'Z';
I would also make Z explicitly a capital letter in case your database settings make it a case-sensitive search.
Have you tried
SELECT * FROM friends WHERE region <= 'zl';?
From the computer's perspective, 'z' < 'zl'
my tables and their layout:
mysql> select * FROM xt_shipping_zones;
+---------+-------------+---------------------------------------------------------------------------+
| zone_id | zone_name | zone_countries |
+---------+-------------+---------------------------------------------------------------------------+
| 5 | ZONE1 | AT,BE,BG,DK,FI,FR,GR,IE,IT,LV,LT,LU,MC,NL,PL,PT,RO,SM,SE,SK,SI,ES,HU,GB |
| 6 | Deutschland | DE |
| 8 | ZONE2Brutto | AD,NO,VA |
| 9 | ZONE2NETTO | CH,LI |
+---------+-------------+---------------------------------------------------------------------------+
mysql> select * FROM xt_shipping_cost WHERE shipping_geo_zone = 99995 LIMIT 5;
+------------------+-------------+-------------------+-----------------------+--------------------------+------------------------+----------------+------------------+
| shipping_cost_id | shipping_id | shipping_geo_zone | shipping_country_code | shipping_type_value_from | shipping_type_value_to | shipping_price | shipping_allowed |
+------------------+-------------+-------------------+-----------------------+--------------------------+------------------------+----------------+------------------+
| 269 | 34 | 99995 | | 0.31 | 17.99 | 17.0000 | 1 |
| 270 | 34 | 99995 | | 17.99 | 35.99 | 34.0000 | 1 |
| 271 | 34 | 99995 | | 35.99 | 53.99 | 51.0000 | 1 |
| 272 | 34 | 99995 | | 53.99 | 71.99 | 68.0000 | 1 |
| 273 | 34 | 99995 | | 71.99 | 89.99 | 85.0000 | 1 |
+------------------+-------------+-------------------+-----------------------+--------------------------+------------------------+----------------+------------------+
mysql> SELECT * FROM geoip WHERE 92569600 BETWEEN start AND end;
+----------+----------+---------+-----+
| start | end | country | id |
+----------+----------+---------+-----+
| 92569600 | 92585983 | AT | 895 |
+----------+----------+---------+-----+
My Query:
SELECT
xt_shipping_cost.shipping_type_value_from,
xt_shipping_cost.shipping_type_value_to,
xt_shipping_cost.shipping_price,
geoip.country
FROM xt_shipping_cost
INNER JOIN xt_shipping_zones
ON xt_shipping_cost.shipping_geo_zone = xt_shipping_zones.zone_id + 99990
INNER JOIN geoip
ON geoip.country REGEXP xt_shipping_zones.zone_countries
WHERE 34664448 BETWEEN geoip.start AND geoip.end
My Problem:
Query is working if there is only ONE entry in xt_shipping_zones.zone_countries like DE. If there are multiple (with comma seperated entries) i cant get a match on that row.
Doing it manually:
mysql> SELECT * FROM `xt_shipping_zones` WHERE `zone_countries` REGEXP 'AT';
+---------+-----------+---------------------------------------------------------------------------+
| zone_id | zone_name | zone_countries |
+---------+-----------+---------------------------------------------------------------------------+
| 5 | ZONE1 | AT,BE,BG,DK,FI,FR,GR,IE,IT,LV,LT,LU,MC,NL,PL,PT,RO,SM,SE,SK,SI,ES,HU,GB |
+---------+-----------+---------------------------------------------------------------------------+
SQLFiddle: http://sqlfiddle.com/#!9/68f8d0/1
I hope i didn't failed to much to make my problem clear.
Thank you
I think you can use find_in_set()
SELECT
xt_shipping_cost.shipping_type_value_from,
xt_shipping_cost.shipping_type_value_to,
xt_shipping_cost.shipping_price,
geoip.country
FROM xt_shipping_cost
INNER JOIN xt_shipping_zones
ON xt_shipping_cost.shipping_geo_zone = xt_shipping_zones.zone_id + 99990
INNER JOIN geoip
ON find_in_set(geoip.country, xt_shipping_zones.zone_countries)
WHERE 34664448 BETWEEN geoip.start AND geoip.end
It is no good idea to store the values as csv. That is very bad database design.
How can I build a query to sort the results by vl_name (vldescription) alphabetically, and subsort table vllinks by vlk_addeddate from the latest with internal limit equal to 1?
SELECT
aa.vl_id, aa.vl_name, aa.vl_code, aa.vl_vcc, aa.vl_description,
bb.vlk_id, bb.vlk_vlid, bb.vlk_link, bb.vlk_platform, bb.vlk_location, bb.vlk_addeddate,
le.vop_vlid, le.vop_thumbnail,
cx.vcc_id, cx.vcc_type, cx.vcc_brand, cx.vcc_variant
FROM vldescription AS aa
LEFT JOIN vllinks AS bb ON aa.vl_id = bb.vlk_vlid
LEFT JOIN vlofferphotos AS le ON le.vop_vlid = aa.vl_id
LEFT JOIN vlcarcats AS cx ON cx.vcc_id = aa.vl_vcc
WHERE aa.vl_vcc = '$change_me_if_you_need'
GROUP BY vl_id
ORDER BY vl_name
Table vlcarcats (vcc_
vcc_id | vcc_type | vcc_brand | vcc_variant
1 | OpenPlace | SomeCorp1 | website
2 | ForPrive | SomeCorp2 | other way
Table vldescription
vl_id | vl_name | vl_code | vl_vcc | vl_description
1 | OpTECC | xDAOcm | 1023 | text, text,...
2 | NewCop | d9MMo2 | 42 | more text,...
Table vllinks (vlk_vlid == vl_id)
vlk_id | vlk_vlid | vlk_link | vlk_platform | vlk_location | vlk_addeddate
1 | 1 | http://... | 1 | USA | 2014-01-10
2 | 2 | http://... | 1 | UK | 2014-01-12
3 | 2 | ftp://... | 2 | UK | 2014-01-15
4 | 2 | ftp://... | 2 | India | 2014-01-19
5 | 1 | ftp://... | 2 | Austria | 2014-01-22
Table vlofferphotos (vop_vlid == vl_id)
vop_vlid | vop_thumbnail
1 | abcdefg.jpg
2 | hijklmn.jpg