SQL JOIN OPENQUERY Assistance - mysql

Looking for advise on the best way to approach the following
TBL1 (Local SQL DB) where ID = varchar
TBL2 (Remote MYSQL DB) where ID = INT
WITH TBL1 as (
SELECT
[Results] as 'ID'
FROM [DB].[results]
),
TBL2 as (
select * from openquery(LINKEDSERVER,'select ID, Name from DB')
)
Select
TBL1.[ID],
TBL2.[NAME]
FROM [DB]
left outer JOIN TBL1 ON TBL1.ID = TBL2.ID
Tried a couple different methods like CAST/CONVERT, but ending up with either an error like "Conversion failed when converting the varchar value '12345
' to data type int." or getting all NULLS for TBL2.
Attempted the following:
WITH TBL1 as
(
SELECT CAST(ISNULL([Results],'0') AS INT) as 'ID'
FROM [DB].[results]
),
TBL2 as ( select * from openquery(LINKEDSERVER,'select ID, Name from DB')
)
Select TBL1.[ID], TBL2.[NAME]
FROM TBL1 Left Outer join TB2 ON TBL1.ID = TBL2.ID
This results in "Conversion failed when converting the varchar value '12345
' to data type int."
Also Attempted:
WITH TBL1 as ( SELECT [Results] as 'ID' FROM [DB].[results]
),
TBL2 as ( select * from openquery(LINKEDSERVER,'select CONVERT(ID, CHAR) AS ID, Name from DB')
)
Select TBL1.[ID], TBL2.[NAME]
FROM TBL1 Left Outer join TB2 ON TBL1.ID = TBL2.ID
This results in the TBL1.ID values being displayed, but all the TBL2.Name values are NULL

Your syntax doesn't look right. Where does the DB C come from? Isn't DB the schema name?
WITH TBL1 as (
SELECT
[Results] as ID
FROM [DB].[results]
),
TBL2 as (
select * from openquery(LINKEDSERVER,'select ID, Name from DB')
)
Select
TBL1.[ID],
TBL2.[NAME]
FROM TBL2 left outer JOIN TBL1 ON try_cast(TBL1.ID as int) = TBL2.ID;

Option 1: Try converting the INT to varchar on the MySQL side of the house. Try to do it right in the sql statement you pass in to the LinkedServer.
WITH TBL1 as ( SELECT [Results] as 'ID' FROM [DB].[results]
),
TBL2 as ( select * from openquery(LINKEDSERVER,'select CONVERT(ID, CHAR) AS ID, Name from DB')
)
Select TBL1.[ID], TBL2.[NAME]
FROM TBL1 Left Outer join TB2 ON TBL1.ID = TBL2.ID
The other option is of course the reverse (if you want to join by INT)
WITH TBL1 as
(
SELECT CAST(ISNULL(TRIM([Results]),'0') AS INT) as 'ID'
FROM [DB].[results]
),
TBL2 as ( select * from openquery(LINKEDSERVER,'select ID, Name from DB')
)
Select TBL1.[ID], TBL2.[NAME]
FROM TBL1 Left Outer join TB2 ON TBL1.ID = TBL2.ID

Appreciate everyone's help. This is what got this working:
WITH TBL1 AS (
SELECT REPLACE(REPLACE(ID, CHAR(13), ''), CHAR(10), '')
FROM DB
WHERE ISNUMERIC(REPLACE(REPLACE(ID, CHAR(13), ''), CHAR(10), '')) = 1
),
TBL2 AS (
SELECT *
FROM OpenQuery(
LINKEDSERVER,
'SELECT id, name FROM DB'
)
)
SELECT
TBL1.ID
,TB2.Name
FROM TBL2
LEFT OUTER JOIN TBL1 ON TBL1.ID = TBL2.id

Related

Wrong count result in mysql when joining two tables

I am trying to join two tables and get the count and grouped by specific field. However, it outputs same count values even if the other table consist only two rows. How should I fix this?
Here's my code:
SELECT tbl1.preferredDay, COUNT(tbl1.preferredDay) as count_1, COUNT(tbl2.preferredDay) as count_2
FROM tblschedule as tbl1
LEFT JOIN tblappointments as tbl2 ON (tbl1.preferredDay = tbl2.preferredDay)
WHERE tbl1.preferredDay = tbl2.preferredDay
GROUP BY preferredDay;
Here is the output but it should be [15, 0][3, 3]
Your query is based on left join it will return the same count().
This is a working query for Mysql 8:
with tbl1 as (
SELECT preferredDay, count(1) as count_1
FROM tblschedule
GROUP BY preferredDay
),
tbl2 as (
SELECT preferredDay, count(1) as count_2
FROM tblappointments
GROUP BY preferredDay
)
select t1.preferredDay, t1.count_1, t2.count_2
from tbl1 t1
inner join tbl2 t2 on t1.preferredDay = t2.preferredDay
There are two WITHs to get separately the count and then an INNER JOIN to join those results
For Mysql 5.7 and lower :
select t1.preferredDay, t1.count_1, t2.count_2
from (
SELECT preferredDay, count(1) as count_1
FROM tblschedule
GROUP BY preferredDay
) as t1
inner join (
SELECT preferredDay, count(1) as count_2
FROM tblappointments
GROUP BY preferredDay
) as t2 on t1.preferredDay = t2.preferredDay

How to emulate a dependent CTE

Following up from this question Possible to emulate a basic CTE in MySQL by in-lining it, would it be possible to in-line the following query in mysql5.7 without the usage of CTEs?
WITH tbl1 AS (
SELECT 1 AS a
), tbl2 AS (
SELECT 1 AS a UNION ALL SELECT 2
), tbl3 AS (
SELECT * FROM tbl1 JOIN tbl2 USING (a)
) SELECT * FROM tbl3, tbl2
If so, how could that be done?
There's no particular problem with doing that, except that you have to repeat tbl2:
SELECT *
FROM (
SELECT *
FROM (
SELECT 1 AS a
) tbl1
JOIN (
SELECT 1 AS a UNION ALL SELECT 2
) tbl2
USING (a)
) tbl3
CROSS JOIN
(
SELECT 1 AS a UNION ALL SELECT 2
) tbl2
fiddle
This would be similar to substituting the body of a function. Writing it in a similar way (conceptually speaking):
let tbl1 = (SELECT 1 AS a) AS tbl1
let tbl2 = (SELECT 1 AS a UNION ALL SELECT 2) AS tbl2
let tbl3 = (SELECT * FROM tbl1 JOIN tbl2 USING (a)) AS tbl3
-- rewriting tbl1 for tbl1 and tbl2
let tbl3 = (SELECT * FROM (SELECT 1 AS a) AS tbl1
JOIN ((SELECT 1 AS a UNION ALL SELECT 2)) AS tbl1 USING (a)) AS tbl3
SELECT * FROM tbl3, tbl2
-- substitutie for tbl3, tbl2
SELECT * FROM
(SELECT * FROM (SELECT 1 AS a) AS tbl1
JOIN ((SELECT 1 AS a UNION ALL SELECT 2)) AS tbl1 USING (a)) AS tbl3,
(SELECT 1 AS a UNION ALL SELECT 2) AS tbl2

Mysql Node.js query fails but works in workbench

I'm getting the callback error 'Incorrect parameters in the call to native function \'json_object\' for the below query in node.js but the same query works when I try it out in the mysql workbench?
SELECT t1.typeId AS typeId,
UNIX_TIMESTAMP(t1.hour) AS hour,
t2.userInfo AS userInfo
FROM UserCommits t1
INNER JOIN ( SELECT t1.id AS id,
JSON_OBJECT("id", t1.id,
"name", t1.name,
"birthUnix", UNIX_TIMESTAMP(t1.birthDate),
"gender", t1.gender,
"image", t2.secure_url,
"connectionInfo", t3.connectionInfo) AS userInfo
FROM Users t1
LEFT JOIN (
SELECT userId,
secure_url
FROM UserProfileImages
WHERE id IN (
SELECT MAX(id)
FROM UserProfileImages
GROUP BY userId
)
) t2
ON t1.id = t2.userId
LEFT JOIN (
SELECT connectionId,
JSON_OBJECT(
"id", id,
"createdUnix", UNIX_TIMESTAMP(createdDt)
) AS connectionInfo
FROM UserConnections
WHERE userId = 98
) t3
ON t1.id = t3.connectionId
) t2
ON t1.userId = t2.id
WHERE t1.locationId = 41
Found the issue..
To insert a JSON_Object from a subquery into another JSON_Object there mysql checks that there is a 1 to 1 relationship. I fixed the issue by updating the subquery to include a Group By statement on the join column.
(
SELECT connectionId,
JSON_OBJECT(
"id", id,
"createdUnix", UNIX_TIMESTAMP(createdDt)
) AS connectionInfo
FROM UserConnections
WHERE id IN (
SELECT MAX(id)
FROM UserConnections
WHERE userId = ${ownerId}
GROUP BY connectionId
)
)

MySQL problem joining 2 tables with UNION

I'm doing UNION in MySQL that I'm unable to troubleshoot for a while.
Error says that
syntax is incorrect around t1.*
Those 2 SELECTs work ok separately, checked. But UNION fails. I'm not custom to MySQL syntax, maybe something is wrong with that.
SELECT (
t1.*,
a.region_count
FROM
(
SELECT
data_region,
COUNT(*) AS region_count
FROM
t2
GROUP BY
data_region
) AS a
LEFT OUTER JOIN
t1
ON
t1.values_att0 = a.data_region
WHERE
t1.name_0 = 'region'
) AS b
UNION
SELECT (
t1.*,
c.age_gen_count
FROM
(
SELECT
data_dage,
data_gen,
COUNT(*) AS age_gen_count
FROM
t2
GROUP BY
data_dage,
data_gen
) AS c
LEFT JOIN
t1
ON
t1.values_att0 = c.data_dage AND
t1.id_question_1 = c.data_gen
WHERE
t1.name_0 = 'age' AND
t1.q_name_1 = 'gen'
)
You are using parenthesis around your SELECT field, this is your syntax error origin (the UNION is not the cause). Just remove them:
SELECT
t1.*,
a.region_count
FROM
(
SELECT
data_region,
COUNT(*) AS region_count
FROM t2
GROUP BY data_region
) AS a
LEFT OUTER JOIN t1
ON t1.values_att0 = a.data_region
WHERE t1.name_0 = 'region'
UNION ALL
SELECT
t1.*,
c.age_gen_count
FROM
(
SELECT
data_dage,
data_gen,
COUNT(*) AS age_gen_count
FROM t2
GROUP BY data_dage, data_gen
) AS c
LEFT JOIN t1
ON t1.values_att0 = c.data_dage
AND t1.id_question_1 = c.data_gen
WHERE t1.name_0 = 'age'
AND t1.q_name_1 = 'gen'

compare two values in sql with eachother

I have a database of magento with double images, I want to delete those but first i got to detect them with a sql query.
I have tried this code
select t1.VALUE from catalog_product_entity_media_gallery t1
join catalog_product_entity_media_gallery t2 on (t1.value = t2.value)
this one:
select * from catalog_product_entity_media_gallery where value=value
and this one:
select
*
from
(
select
value
from
catalog_product_entity_media_gallery
group by
value
having count(*) > 1
) as t
inner join catalog_product_entity_media_gallery on (
catalog_product_entity_media_gallery.value = t.value
)
the first gives an error and the second- and third one gives back every product.
Give this one a try:
select
*
from (
select
entity_id,attribute_id,value,
MIN(value_id) value_id
from catalog_product_entity_media_gallery
group by
entity_id,attribute_id,value
having COUNT(*) > 1
) A1
inner join catalog_product_entity_media_gallery A2 on
A1.entity_id = A2.entity_id and
A1.attribute_id = A2.attribute_id and
A1.value = A2.value and
A1.value_id = A2.value_id
You can just get the min id by value, then except the other records:
select
*
from catalog_product_entity_media_gallery t1
where exists
( select * from
(select value, min(value_id) as min_value_id
from catalog_product_entity_media_gallery
group by value
) as t2
where t1.value=t2.value and t1.value_id=t2.min_value_id
)
If you want delete the duplicated rows, change exists to not exists.
delete
from catalog_product_entity_media_gallery t1
where not exists
( select * from
(select value, min(value_id) as min_value_id
from catalog_product_entity_media_gallery
group by value
) as t2
where t1.value=t2.value and t1.value_id=t2.min_value_id
)