mysql Left Join on POINT datatype - mysql

I have two table that each of them have a column with point (spatial) datatype like this :
Table 1 :
id latlng
------------------------------
1 POINT(35.72036 51.42124)
2 POINT(32.74446 53.42124)
3 POINT(31.78676 51.44564)
4 POINT(32.73436 54.42124)
Table 2:
id latlng
------------------------------
1 POINT(35.719 51.4221)
2 POINT(35.72036 51.42124)
3 POINT(32.74446 53.42124)
4 POINT(31.78676 51.44564)
5 POINT(32.73436 54.42124)
6 POINT(35.72379 51.4144)
Now i want to join these two table in together with LEFT JOIN statement on Table 2
i wrote this query but it returns 24 rows! i should be 6 rows like table 2.
SELECT * FROM Table2 LEFT JOIN Table1 ON Table2.latlng = Table1.latlng
is there any way to resolve this problem & just get 6 rows?

i think you forgot GROUP BY
try this
SELECT * FROM Table2
LEFT JOIN Table1
ON Table2.latlng = Table1.latlng
GROUP BY Table2.id

Related

MySql query Get all rows from left table and common from right table

Table 1 - customer_kitchen_service_plans and data https://prnt.sc/00_ip7uWiQuq
Table 2 - kitchen_service_plans_linking and data https://prnt.sc/e_GW64THTCFK
Above two are the tables and i want to join in such a way that it should return All the rows from Table 1 and Common rows from Table 2
Join using column kitchen_service_plan_id from Table 1 and kitchen_service_plan_parent_id from Table 2
Current query is as below
select * from `customer_kitchen_service_plans` as `cksp`
left join `kitchen_service_plans_linking` as `kspl` on
`kspl`.`kitchen_service_plan_parent_id` =
`cksp`.`kitchen_service_plan_id`
where `cksp`.`status` = 'ACTIVE' and `cksp`.`customer_id` = 2
You want a left outer join which returns all rows from the first table and matching rows from the right.
select * from `customer_kitchen_service_plans` as cksp
left outer join `kitchen_service_plans_linking` as kspl on
kspl.`kitchen_service_plan_parent_id` =
cksp.`kitchen_service_plan_id`
where cksp.`status` = 'ACTIVE' and cksp.`customer_id` = 2
Here's a discussion on Left Outer Join in MySQL
See if that's help
SELECT * FROM customer_kitchen_service_plans
LEFT JOIN kitchen_service_plans_linking ON
customer_kitchen_service_plans.kitchen_service_plan_id=
kitchen_service_plans_linking.kitchen_service_plan_parent_id;

My SQL query involving multiple tables

I have 2 tables. First table stores id in multiple column whose value is stored in other table. I want a query that returns result which has structure of my 1st table but values from 2nd table. To be more specific let's say I have a table like this:
Table A:
Uniqueid song_1 song_2 song_3 song_4 song_5
1 2 4 5 6 8
Table B:
song_id song_name
1 abcd
2 def
3 efg
4 ghi
5 abdal
6 nsadln
7 knwldn
8 jdkabdb
I want to fetch data from Table A but it should look like:
Desired result:
Uniqueid song_1 song_2 song_3 song_4 song_5
1 def ghi abdal nsadln jdkabdb
I have used join and making objects but no luck so far. Please help me out.
Just use a bunch of left joins to get to your answer:
SELECT
a.UniqueId
,s1.song_name as song_1
,s2.song_name as song_2
,s3.song_name as song_3
,s4.song_name as song_4
,s5.song_name as song_5
FROM
TableA a
LEFT JOIN TableB s1
ON a.song_1 = s1.song_id
LEFT JOIN TableB s2
ON a.song_2 = s2.song_id
LEFT JOIN TableB s3
ON a.song_3 = s3.song_id
LEFT JOIN TableB s4
ON a.song_4 = s4.song_id
LEFT JOIN TableB s5
ON a.song_5 = s5.song_id

SQL Find closest timestmaps when duplicates exists

I cant find topic to my problem, so i'm asking here.
I have select:
SELECT t1.*,
t2.unixtimestamp as rj_time,
t2.response_detail as rj_error
FROM t1
LEFT JOIN table2 as t2
ON t1.id=t2.personid
AND t1.clientcode=t2.client
WHERE t1.clientcode='quouk'
AND (t1.language = 'en_GB')
ORDER BY t1.id
TABLE 1:
id clientcode language
1 quouk en_GB
2 quouk en_GB
3 quouk en_GB
TABLE 2:
id personid client language unixtimestamp response_detail
1 1 quouk en_GB 1393401000 error
2 1 quouk en_GB 1393401001 error
3 2 quouk en_GB 1393404600 error
4 2 quouk en_GB 1393404601 error
5 3 quouk en_GB 1393257900 error
6 3 quouk en_GB 1393257901 error
So if i am launching this query, it returning to me 6 rows, but the result should be 3 rows (from table 2 : 2, 4, 6 id's). If you will look into timestamps you will see a small difference between rows. That means i need to find closest dates to now. I saw a lot of solutions to use LIMIT at the end of the query, but i think it is a bit different in my case.
Assuming the timestamps are not in the future then the nearest one to now will be the latest one.
As such you can probably do this by adding a simple LEFT JOIN against a sub query:-
SELECT t1.*, t2.unixtimestamp as rj_time, t2.response_detail as rj_error
FROM t1
LEFT OUTER JOIN
(
SELECT personid, client, MAX(unixtimestamp) AS MaxTimeStamp
FROM table2
GROUP BY personid, clientcode
) Sub1
ON t1.id = Sub1.personid AND t1.clientcode = Sub1.client
LEFT OUTER JOIN table2 as t2
ON Sub1.personid=t2.personid AND Sub1.client = t2.client AND Sub1.MaxTimeStamp = t2.unixtimestamp
WHERE t1.clientcode='quouk'
AND (t1.language = 'en_GB')
ORDER BY t1.id
This gets the latest timestamp for each person / client from table2, and then joins that against table2 to get the other columns that are required (ie response_detail). If you just used MAX then you would possibly not get the correct value of response_detail as that would come from an undefined row rather than from the row that the MAX applies to.
SELECT t1.*, MAX(t2.unixtimestamp as rj_time), t2.response_detail as rj_error
FROM t1
LEFT JOIN table2 as t2 ON t1.id=t2.personid AND t1.clientcode=t2.client
WHERE t1.clientcode='quouk'
AND (t1.language = 'en_GB')
GROUP BY t1.id
ORDER BY t1.id

join or select in on multiple fields

(The example that follows is hypothetical, but illustrates the concept).
Using MySQL, say I have 2 tables:
userFromID userToId moreInfo
1 2 cat
1 3 dog
4 1 bear
3 4 fish
And...
userId someInfo addlInfo
1 m 32
2 f 33
3 m 25
4 f 28
And I want to query for a user id, and get back joined info from both tables for all users that share a relationship with user1.
assume that the first table has something like alter table thatFirstTable add unique index(userFromId, userToId) so there won't be any duplicates - each relationship between the two ids will be unique.
it doesn't matter who's the "from" or "to"
so the desired result would be something like this, if queried for relationships with user id: 1
userId moreInfo someInfo addlInfo
2 cat f 33
3 dog m 25
4 bear f 28
Thanks.
/EDIT this "works" but I suspect there's a better way?
SELECT * FROM users JOIN friends ON friends.userFrom = users.id OR friends.userTo = users.id WHERE users.id != 1 AND friends.userFrom = 1 OR friends.userTo = 1
/EDIT2 - I updated the sample output to better reflect the goal
try this query::
select tbl2.userid,tbl1.moreinfo,
tbl2.someinfo,tbl2.addinfo
from tbl1 join tbl2
on (tbl1.usertoid = tbl2.userid and tbl1.userfromid = 1)
You should just join the tables with the query below.
select u.userId, f.moreInfo, u.someInfo, u.addlInfo
from users AS u INNER JOIN friends AS f ON u.userId = f.UserToId
where f.userFrom = 1
Try this. Tested and 100% working
select a.userToID, a.moreInfo, b.someInfo, b.addInfo from tbl1 a
left outer join
tbl2 b on a.userToID = b.userId
where a.userFromID = 1;

How to left join or inner join a table itself

I have this data in a table, for instance,
id name parent parent_id
1 add self 100
2 manage null 100
3 add 10 200
4 manage null 200
5 add 20 300
6 manage null 300
How can I left join or inner join this table itself so I get this result below?
id name parent
2 manage self
4 manage 10
6 manage 20
As you can I that I just want to query the row with the keyword of 'manage' but I want the column parent's data in add's row as the as in manage's row in the result.
Is it possible?
EDIT:
the simplified version of my actual table - system,
system_id parent_id type function_name name main_parent make_accessible sort
31 30 left main Main NULL 0 1
32 31 left page_main_add Add self 0 1
33 31 left page_main_manage Manage NULL 0 2
my actual query and it is quite messy already...
SELECT
a.system_id,
a.main_parent,
b.name,
b.make_accessible,
b.sort
FROM system AS a
INNER JOIN -- self --
(
SELECT system_id, name, make_accessible, sort
FROM system AS s2
LEFT JOIN -- search --
(
SELECT system_id AS parent_id
FROM system AS s1
WHERE s1.function_name = 'page'
) AS s1
ON s1.parent_id = s2.parent_id
WHERE s2.parent_id = s1.parent_id
AND s2.system_id != s1.parent_id
ORDER BY s2.sort ASC
) b
ON b.system_id = a.parent_id
WHERE a.function_name LIKE '%manage%'
ORDER BY b.sort ASC
result I get currently,
system_id main_parent name make_accessible sort
33 NULL Main 0 1
but I am after this,
system_id main_parent name make_accessible sort
33 self Main 0 1
You just need to reference the table twice:
select t1.id, t1.name, t2.id, t2.name
from TableA t1
inner join TableA t2
on t1.parent_id = t2.Id
Replace inner with left join if you want to see roots in the list.
UPDATE:
I misread your question. It seems to me that you always have two rows, manage one and add one. To get to "Add" from manage:
select system.*, (select parent
from system s2
where s2.parent_id = system.parent_id
and s2.name = 'add')
AS parent
from system
where name = 'manage'
Or, you might split the table into two derived tables and join them by parent_id:
select *
from system
inner join
(
select * from system where name = 'add'
) s2
on system.parent_id = s2.parent_id
where system.name = 'manage'
This will allow you to use all the columns from s2.
Your data does not abide to a child-parent hierarchical structure. For example, your column parent holds the value 10, which is not the value of any id, so a child-parent association is not possible.
In other words, there's nothing that relates the record 2,manage,null to the record 1,add,self, or the record 4,manage,null to 3,add,10, as you intend to do in your query.
To represent hierarchical data, you usually need a table that has a foreign key referencing it's own primary key. So your column parent must reference the column id, then you can express a child-parent relationship between manage and add. Currently, that's not possible.
UPDATED: Joining by parent_id, try:
select m.id, m.name, a.parent
from myTable m
join myTable a on m.parent_id = a.parent_id and a.name = 'add'
where m.name = 'manage'
Change the inner join to a left join if there may not be a corresponding add row.