I have three tables, A,B and C
Tables A and B have an ID and other fields, table C is a n-n relationship of A and B (C contains only IDS of A and B with primary key(id_a, id_b) and foreign key).
Now I need to verify if a row of A has the same associations of another row of A.
EXAMPLE
A = [id_a] = [1,2,3,4]
B = [id_b] = [1,2,3,4]
C = [id_a, id_b] = [[1,1],[1,3],[2,1],[2,3],[3,3]]
In this case, I need to extract only records where id_a are 1 and 2, because they are both associated with the same row of B (id_b 1 and 3).
id_a=3 is not the same as id_a=1/2, because it isn’t associated with id_b=1
This is for a new Ubuntu 18.04 server, running MySQL, PHP 7 (LAMP stack)
Example with id_a=1
SELECT id_a
FROM C
WHERE id_b IN (SELECT id_b FROM B WHERE id_a=1)
GROUP BY id_a;
The simplest method for an exact match uses group_concat():
select c.id_a
from (select c.id_a, group_concat(c.id_b order by c.id_b) as id_bs
from c
group by c.id_a
) c join
(select group_concat(c.id_b order by c.id_b) as id_bs
from c
where c.id_a = #id_a
) ac
on c.id_bs = ac.id_bs
Related
I am trying to get a row of another table as a sub-query of the SELECT query.
SELECT g.ip, g.version, t.testid, t.status, m.rundate, t.runid , (select * from B where runid=t.runid and testid=t.testid)
FROM Tests t, Master m, Env g
WHERE t.runid=m.runid
AND t.runid=g.runid
AND g.version = "1.2.3"
AND t.testid like "%test_name%"
AND g.ip in ("198.18.111.222")
order by m.rundate desc;
How can this be achieved?
Thanks!
Try with this:
SELECT g.ip, g.version, t.testid, t.status, m.rundate, t.runid , c.* from B c
Join Tests t on t.runid =t.testid
join Master m on t.runid=m.runid
join Env g on t.runid=g.runid
WHERE g.version = "1.2.3" AND t.testid like "%test_name%"
AND g.ip in ("198.18.111.222")
order by m.rundate desc;
at line 2 if there is any id in B table which matches with the id in Tests
replace t.runid = t.testid (suppose if you have runid in B table which relates to test table testid then replace with c.runid = t.testid)to the requirement in which the B table and tests table are satisfying the scenario of matching ID's(PK and FK).
I have the following table:
table A
id emp emp_dst
1 a b
2 a d
3 b c
4 b a
5 c d
6 d a
7 d b
8 d c
my sql query should return me the following simplified table since a = b equals b = a
table B
emp emp_dst
a b
a d
b c
d b
d c
but I have no idea how to do this in an sql query in MYSQL,
try revising expressions with UNION but the results are wrong
An alternative that suits my personal preferences better...
(Based on your comment that the id in the results was not relevant.)
SELECT
CASE WHEN emp <= emp_dst THEN emp ELSE emp_dst END AS emp,
CASE WHEN emp <= emp_dst THEN emp_dst ELSE emp END AS emp_dst
FROM
yourTable
GROUP BY
1, 2
ORDER BY
1, 2
If you want an id, then you can add MIN(id). Just note that the id found may actually have the two values the other way around.
An alternative that uses a LEFT JOIN rather than GROUP BY.
SELECT
yourTable.*
FROM
yourTable
LEFT JOIN
yourTable AS reflection
ON reflection.emp_dst = yourTable.emp
AND reflection.emp = yourTable.emp_dst
AND reflection.id <> yourTable.id
WHERE
(reflection.id IS NULL)
OR (yourTable.emp < reflection.emp_dst)
OR (yourTable.emp = reflection.emp_dst AND yourTable.id < reflection.id)
ORDER BY
yourTable.emp,
yourTable.emp_dst
(The last OR is only needed if a table can have 'a', 'a', and it appear twice.)
Note: This may benefit from having two indexes...
CREATE INDEX yourTable_e_ed_id ON yourTable( emp, emp_dst, id );
CREATE INDEX yourTable_ed_e_id ON yourTable( emp_dst, emp, id );
I am trying to run a select statement on two different servers that have some matching primary keys. I want to be able to select the primary key but add the prefix 'A' to every record
ex:
ID "to this" ID
1 A1
2 A2
3 A3
This is what I have for the query
select 'A' + CAST (a.id AS VARCHAR(25)) as ID,a.*,':', b.*,':',c.*,':', d.*,':', e.*,'REPORTDT', g.*
from labgen.order_ a
join patient b on a.id = b.chart
join insurance c on b.ins1 = c.code
join client d on d.num = a.client1
join salesgrp e on d.salesgroup = e.num
join reportdt g on a.accession = g.accession
Try this in the select statement:
select CONCAT('A', a.id) as ID, a.*,':', //etc
This link will also help.
I need help with a data extraction. I'm an sql noob and I think I have a serious issue with my data design skills. DB system is MYSQL running on Linux.
Table A is structured like this one:
TYPE SUBTYPE ID
-------------------
xyz aaa 0001
xyz aab 0001
xyz aac 0001
xyz aad 0001
xyz aaa 0002
xyz aaj 0002
xyz aac 0002
xyz aav 0002
Table B is:
TYPE1 SUBTYPE1 TYPE2 SUBTYPE2
-------------------------------------
xyz aaa xyz aab
xyz aac xyz aad
Looking at whole table A, I need to extract all rows where both type and subtype are present as columns in a single table B row. Of course this condition is never met since A.subtype can't be at same time equal to B.subtype1 AND B.subtype2 ...
In the example the result set for id should be:
xyz aaa 0001
xyz aab 0001
xyz aac 0001
xyz aad 0001
I m trying to use a join with 2 AND conditions, but of course I got an empty set.
EDIT:
#Barmar thank you for your support. It seems that I m really near the final solution. Just to keep things clear, I opened this thread with a shortened and simplified data structure, just to highlight the point where I was stuck.
I thought about your solution, and is acceptable to have both result on a single row. Now, I need to reduce execution time.
First join takes about 2 minutes to complete, and it produce around 23Million of rows. The second join (table B) is probably taking longer.
In fact, I need 3 hours to have the final set of 10 millions of rows. How can we impove things a bit? I noticed that mysql engine is not threaded, and the query is only using a single CPU. I indexed all fields used by join, but I m not sure its the right thing to do...since I m not a DBA
I suppose also having to rely on VARCHAR comparison for such a big join is not the best solution. Probably I should rewrite things using numerical ID that should be faster..
Probably split things into different query will help parallelism. thanks for a feedback
You can join Table A with itself to find all combinations of types and subtypes with the same ID, then compare them with the values in Table B.
SELECT t1.type AS type1, t1.subtype AS subtype1, t2.type AS type2, t2.subtype AS subtype2, t1.id
FROM TableA AS t1
JOIN TableA AS t2 ON t1.id = t2.id AND NOT (t1.type = t2.type AND t1.subtype = t2.subtype)
JOIN TableB AS b ON t1.type = b.type1 AND t1.subtype = b.subtype1 AND t2.type = b.type2 AND t2.subtype = b.subtype2
This returns the two rows from Table A as a single row in the result, rather than as separate rows, I hope that's OK. If you need to split them up, you can move this into a subquery and join it back with the original table A to return each row.
SELECT a.*
FROM TableA AS a
JOIN (the above query) AS x
ON a.id = x.id AND
((a.type = x.type1 AND a.subtype = x.subtype1)
OR
(a.type = x.type2 AND a.subtype = x.subtype2))
DEMO
You can use EXISTS:
SELECT a.*
FROM TableA a
WHERE EXISTS(
SELECT 1
FROM TableB b
WHERE
(b.Type1 = a.Type AND b.SubType1 = a.SubType)
OR (b.Type2 = a.Type AND b.SubType2 = a.SubType)
)
AND a.ID = '0001'
ONLINE DEMO
You can use Join like this :
Select A.Type, A.SubType, A.ID from a_table A JOIN b_table B
ON (A.Type = B.Type1 AND A.SubType = B.SubType1) OR
(A.Type = B.Type2 AND A.SubType = B.SubType2)
But I think there is a problem in your design, you have same values in Table A with different ID and there is no any condition on ID !
Instead of storing Type and SubType in Table B, you can store an unique ID of each record of Table A to Table B, then you can think about better ways to get results you want ...
Edit :
With UNION of two joins you can get that result :
Select A.Type, A.SubType, A.ID from A_table A
JOIN b_table B1 ON A.Type = B1.Type1 AND A.SubType = B1.SubType1
WHERE (B1.Type2, B1.SubType2) IN (SELECT Type, SubType FROM A_table) AND ID = '0001'
UNION
Select A.Type, A.SubType, A.ID from A_table A
JOIN b_table B2 ON A.Type = B2.Type2 AND A.SubType = B2.SubType2
WHERE (B2.Type1, B2.SubType1) IN (SELECT Type, SubType FROM A_table) AND ID = '0001'
But as I say, I think there is a design problem, it seems better that each type and subtype have an unique ID in Table A and work with this ID on Table B
I have 2 tables, one for the articles and one for some attributes
I have some products that have one attribute with value Yes. I also have other attributes.
The query that i want to create is to get all products that don't have the Attribute 7.
You can check the mysql tables.
http://sqlfiddle.com/#!2/f75eec/1
select a.ArticleID,a.ArticleTitle,aa.ArticleID,aa.AttrID,aa.StringValue
from cms_articles a
inner join cms_attr_art aa on aa.ArticleID = a.ArticleID
where a.ArticleID NOT IN (select ArticleID from cms_attr_art where AttrID = 7);
You can use this query
SELECT a.ArticleId, b.attrId
FROM cms_articles a
INNER JOIN cms_attr_art b
ON a.articleId = b.articleId
WHERE NOT EXISTS (SELECT 1 FROM cms_attr_art c WHERE c.articleid = a.articleid AND c.attrId = 7)