SQL statement to get IDs with a specific condition? - mysql

I have a table called Cats with two columns (shortId, LongId)
And another table called cat-to-cat-dependency that has two columns (sourceShortId, targetShortId)
I want to return a list of all the source Cat LongIds given a target Cat LongId.
My sql statement is
SELECT C.LongID
FROM CAT C INNER JOIN
CAT-TO-CAT-DEPENDENCY CD
ON CD.sourceShortId = CAT.shortId
WHERE CAT.LongID = '1234'
But this always just returns the value that I input.

Try this query:
select C1.LongId
from cat-to-cat-dependency CD
join Cats C1 on C1.shortId = CD.sourceShortId
join Cats C2 on C2.shortId = CD.targetShortId
where C2.LongId = '1234'

Related

Why after LEFT JOIN some rows duplicate itself?

transaction_jobs table
transaction_lines table
SQL executed :
SELECT
tj.id AS tj_id, tj.debit AS tj_debit, tj.credit AS tj_credit, job_id AS tj_job_id,
tl.id AS tl_id, tl.debit AS tl_debit, tl.credit AS tl_credit
FROM transaction_jobs tj
LEFT JOIN transaction_lines tl ON tl.account_id = tj.account_id AND tl.transaction_id = tj.transaction_id
WHERE tj.transaction_id = 198044 AND tj.account_id = 64375
Executed code result:
Result I expected:
Is there a way I could get the result I expected?
You have multiple records of the same transaction on both tables and are matching multiple times.
TJ ID 385610 will match once with TL ID 2277 and again with TL ID 2278. because both have transaction_id 198044.
If you wish for the results to be only one match, you need to use
GROUP BY tj_transaction_id
You can read more here:
https://dev.mysql.com/doc/refman/8.0/en/group-by-modifiers.html

Sql query Cross Transform or Pivot?

I have this query for MySql database:
SELECT
pim_pimcore_database.object_query_RGL.rulecode AS "rulecode",
pim_pimcore_database.object_query_RGL.DescrizioneRegola AS "rule_desc",
pim_pimcore_database.object_relations_RGL.position AS "id",
pim_pimcore_database.objects.o_classId,
pim_pimcore_database.objects.o_key,
pim_pimcore_database.object_collection_ruleIF_RGL.Operatore,
pim_pimcore_database.object_collection_ruleIF_RGL.Concatenatore
FROM
pim_pimcore_database.object_query_RGL
LEFT JOIN pim_pimcore_database.object_relations_RGL
ON pim_pimcore_database.object_query_RGL.oo_id =
pim_pimcore_database.object_relations_RGL.src_id
LEFT JOIN pim_pimcore_database.objects
ON pim_pimcore_database.object_relations_RGL.dest_id = pim_pimcore_database.objects.o_id
LEFT JOIN pim_pimcore_database.object_collection_ruleIF_RGL
ON pim_pimcore_database.object_relations_RGL.position =
pim_pimcore_database.object_collection_ruleIF_RGL.`index`
AND pim_pimcore_database.object_relations_RGL.src_id =
pim_pimcore_database.object_collection_ruleIF_RGL.o_id
GROUP BY
pim_pimcore_database.object_relations_RGL.position AS "ID"
WHERE
pim_pimcore_database.object_query_RGL.oo_id = 1042 AND
pim_pimcore_database.object_relations_RGL.ownername ="IfStatement"
That gives me the result:
But what I need is table like this:
How do I change the query for the desired output?
Your cartesian product (doubling of the rows) appears to come from joining pim_pimcore_database.objects on o_id.
If instead you represent this table twice in the query (join it twice) with relevant aliases and a predicate that selects only those kind of o_classid relevant to that alias, then the cartesian will disappear and you'll get the result you seek:
SELECT
...,
o_opt.key as OPT,
o_com.key as COM,
...
LEFT JOIN pim_pimcore_database.objects o_opt ON ... AND o_opt.o_classid = 'OPT'
LEFT JOIN pim_pimcore_database.objects o_com ON ... AND o_com.o_classid = 'COM'

Returning value from query based on results

I have this query I'm trying to build to display specific information for a stored table. I'm needing the query to also display the Enemy Guild Name but I'm having trouble getting the query to take the Enemy Guild ID and link it to the name.
SELECT g.wPos as wPos, g.szGuildName as szGuildName, g.dwGuildExpWeek as dwGuildExpWeek, g.dwEnemyGuildID as dwEnemyGuildID, gm.wPower as wPower, gd.szName as szName
FROM guild as g
LEFT JOIN guild_member AS gm ON gm.dwGuildID = g.dwGuildID AND gm.wPower = '1'
LEFT JOIN gamedata AS gd ON gd.dwID = gm.dwRoleID
WHERE g.wPos = '1'
The output of the query right now results in the following:
Query Results Currently
What I need it to do now is take the dwEnemyGuildID it finds and then use that ID to search for the szGuildName while also displaying the other data it finds.
Use the concept of SELF JOIN, in which we will join same table again if we have a field which is a reference to the same table. Here dwEnemyGuildID is reference to the same table.
A trivial example of the same is finding Manager for an employee from employees table.
Reference: Find the employee id, name along with their manager_id and name
SELECT
g.wPos as wPos,
g.szGuildName as szGuildName,
g.dwGuildExpWeek as dwGuildExpWeek,
g.dwEnemyGuildID as dwEnemyGuildID,
enemy_g.szGuildName as szEnemyGuildName, -- pick name from self joined table
gm.wPower as wPower,
gd.szName as szName
FROM guild as g
LEFT JOIN guild_member AS gm ON gm.dwGuildID = g.dwGuildID AND gm.wPower = '1'
LEFT JOIN guild AS enemy_g ON g.dwEnemyGuildID = enemy_g.dwGuildID -- Use self join
LEFT JOIN gamedata AS gd ON gd.dwID = gm.dwRoleID
WHERE g.wPos = '1';

JOIN two sql SELECT statements where one has single record and other has multiple records

I have tow tables, the first is mda_alert_info and the second is key_contacts_info. For each alert set up there may be multiple corresponding contacts. Both tables are linked by 3 columns mda_id, stage_id and ref_number and during the query I will have to pass figures values for them
How do I get all what I want from both tables in one statement. Below are the individual SELECT statements.
$result = mysql_query("SELECT `mda_name`, `project_name`, `ipc_id` FROM `mda_alert_info` WHERE `stage_id`=1 AND `mda_id`=2 AND `ref_number`= '444'");
This will always return one record
$result = mysql_query("SELECT `contact_role`, `contact_email`, `contact_ph_number` FROM `key_contacts_info` WHERE `stage_id`=1 AND `mda_id`=2 AND `role`=0 AND `ref_number`='444'");
This may return multiple records
I tried for a while and couldn't get it to work so I tried adding another field called 'me' to both tables which is basically concatting mda_id and stage_id strings then I tried the query below.
$result = mysql_query("SELECT key_contacts_info.contact_role, key_contacts_info.contact_email, key_contacts_info.contact_ph_number, mda_alert_info.mda_name, mda_alert_info.project_name, mda_alert_info.ipc_id FROM key_contacts_info LEFT JOIN mda_alert_info ON key_contacts_info.me = mda_alert_info.me WHERE stage_id=1 AND mda_id=2 AND role=0 AND ref_number='444'");
But it's still not working. What am I doing wrong and how do I get it to work.
UPDATE:
Sorry but I should clarify something on the relationship between the tables the three columns exist on each table but are not primary keys on either of the tables
SELECT a.*, b.*
FROM mda_alert_info a
INNER JOIN key_contacts_info b
ON a.mda_id = b.mda_id AND
a.stage_id = b.stage_id AND
a.ref_number = b.ref_number
WHERE b.role = 0 AND
a.stage_id = 1 AND
a.mda_id = 2 AND
a.ref_number = '444'
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
select
a.mda_name,
a.project_name,
a.lpc_id,
k.contact_role,
k.contact_email,
k.contact_ph_number
from mda_alert_info a
join key_contacts_info k
on a.state_id = k.state_id
and a.mda_id = k.mda_id
and a.ref_number = k.ref_number
where a.state_id = 1
and a.mda_id = 2
and a.ref_number = '444'
and k.role = 0
;

MySQL Join tables, if criteria not met still return as null

I have this MySQL query
SELECT perms.permission_id, perms.long_title, perms.category, gperms.value FROM
acl_permissions AS perms JOIN acl_group_permissions AS gperms ON
(perms.permission_id = gperms.permission_id AND gperms.group_id = 1) WHERE
perms.type IN ('adm', 'cs') AND perms.simple_title NOT IN ('adm_', 'cs_')
ORDER BY perms.long_title
Basically the bit causing problems is in the ON. I want the query to return all rows from perms based on the where criteria regardless of whether there is a row matching gperms.group_id = 1.
gperms.value would ideally just be an empty string if there was no row matching gperms.group_id = 1.
You want to LEFT OUTER JOIN (or LEFT JOIN for short) gperms instead of just a straight join
SELECT perms.permission_id, perms.long_title, perms.category, gperms.value
FROM acl_permissions AS perms
LEFT JOIN acl_group_permissions AS gperms
ON (perms.permission_id = gperms.permission_id AND gperms.group_id = 1)
WHERE perms.type IN ('adm', 'cs')
AND perms.simple_title NOT IN ('adm_', 'cs_')
ORDER BY perms.long_title
which will return NULL for gperms.value for any row that doesn't join the gperms on the given condition.
If you want an empty string instead of the NULL you can use IFNULL():
SELECT perms.permission_id, perms.long_title, perms.category, IFNULL(gperms.value,'')