I have Table Having 2 columns
Cust1 Cust2
A B
C A
A C
C D
B A
D C
We need to remove these duplicates and retain only one combination
So Output could be either
Cust1 Cust2
A B
A C
C D
OR
Cust1 Cust 2
B A
C A
D C
Selecting unique combinations:
SELECT DISTINCT LEAST(Cust1, Cust2) Cust1,
GREATEST(Cust1, Cust2) Cust2
FROM source_table
Removing "duplicates" (assuming that there is no full duplicated rows, by both values and order - they won't be removed):
DELETE t1.*
FROM source_table t1
JOIN source_table t2 ON (t1.Cust1, t1.Cust2) = (t2.Cust2, t2.Cust1)
WHERE t1.Cust1 > t1.Cust2
Recommendation - create unique index by (LEAST(Cust1, Cust2), GREATEST(Cust1, Cust2)), it will forbid duplicates insertion.
If you have pairs in both directions, then the simplest method is:
select t.*
from t
where cust1 < cust2;
If you want to modify the table, then:
delete t from t
where cust1 > cust2;
Both of these can be modified to handle singletons, but there are no examples in your question.
Related
I have a requirement where If a certain conditions matches then I need to apply JOIN otherwise, I don't need to apply it.
for example
A,B and C are tables
so I need to join B and C if the B.id not in (select entityId from A) otherwise there will be no join.
also here A and C don't have common values.
Table A
id entityId name
1 xyz abc
2 bcd z
3 edc x
Table B
id entityId shopRegID
1 bcd z
Table C
id entityId newEntityID ShopNewname
1 xyz xyze abcd
2 e ee sd
now I have condition like this, where I need to get the data from these table ,based on the entityId provided to me.
I need to eliminate all the shops which are not registered(not in table B) but include the shops which are renamed(in table C but not in B)
suppose If I am given ('xyz','bcd','edc')
the output should contains
bcd (because it's in table B)
xyz (because it's in table C)
and these table have very large amount of data(in 100 thousands )
what is the best and performant way to achive this.
You can use left join and coalesce as follows:
select *
from tableA A
left join tableB B on a.entityid = b.entityid
left join tableB C on a.entityid = c.entityid
WHERE coalesce(b.entityid,c.entityid) is not null
It sounds like you want entities from a that are in either of the tables. This suggests exists logic:
select a.*
from a
where exists (select 1 from b where b.entityId = a.entityId) or
exists (select 1 from c where c.entityId = a.entityId)
I have a table that contains as comma separated values in three fields the primary keys of three different tables, for example:
Table A (Main table):
id title companyid countryid regulatorid
1 tit1 1,2 2,3 2,1
2 tit2 3,1 1,2 1,3
Table B (company) table c (Country) table d(regulator)
id title id title id title
1 comp1 1 country1 1 regul1
2 comp2 2 country2 2 regulator2
3 comp3 3 country3 3 regulator
I want to get a result like:
id title company country regulator
1 tit1 comp1,comp2 country2,counrtry3 regulator2,regul1
2 tit2 comp3,comp1 country1,country2 regul1,regulator3
I have made query like:
select id,title,group_concat(table B.title) AS company,group_concat(table c.title) AS
country,group_concat(table d.title) AS regulator from table A INNER JOIN table b on
find_in_set(table B.id,table A.companyid) > 0 INNER JOIN table c on find_in_set(table
c.id,table A.countryid) > 0 INNER JOIN table d on find_in_set(table d.id,table
A.regulatorid) > 0
What do I have to change to get the current result?
This is such a horrible data format that before answering, I should make you promise to change the format if you have control over it. This should really be three additional separate association/junction tables. If you are going to use a relational database, use it right.
select a.id, a.title, group_concat(distinct b.title), group_concat(distinct c.title),
group_concat(distinct d.title)
from a left outer join
b
on find_in_set(b.id, a.companyid) > 0 left outer join
c
on find_in_set(c.id, a.countryid) > 0 left outer join
d
on find_in_set(d.id, a.regulatorid) > 0
group by a.id, a.title;
But it would be much much much better to change the table layout.
I have two tables. Table A and B. Each table has a barcode column.
I can join these two on the barcode field. What I want to do is find out which barcodes from table A don't join with B.
For example:
A has:
001
002
003
B has:
001
003
I need a query that will pull back 002.
How do I do that?
This is known as an anti-join, for which you have three options in MySQL. In some vague order of preference (most to least):
OUTER JOIN and IS NULL:
SELECT A.barcode
FROM A LEFT JOIN B USING (barcode)
WHERE B.barcode IS NULL
NOT IN:
SELECT barcode
FROM A
WHERE barcode NOT IN (
SELECT barcode
FROM B
)
NOT EXISTS:
SELECT barcode
FROM A
WHERE NOT EXISTS (
SELECT *
FROM B
WHERE B.barcode = A.barcode
)
See #Quassnoi's blog article, NOT IN vs. NOT EXISTS vs. LEFT JOIN / IS NULL: MySQL for a comparative analysis of their respective performance.
I have three tables like A,B,C and here what my requirement is
in A table having two foreign key from B and C table and
I want if b_id is not null then get data from the B table
else if c_id is not null then get data from the C table.
B and C Tables having the three to four colums. Please see the following structure.
A Table
a_id(pk) | b_id(fk) | C_id(fk)
1 | null | 1
2 | 2 | null
For that above requirement i tried but not achieve my goal. please anybody to do this.
Thanks in advance
If I understand correctly your question you want to do a left join on tables B and C
Select B.*, C.*
From table_A A left join Table_B B on A.B_Id=B.Id
left join Table_C C on A.C_Id = C.Id
Probably you mean to have left joins on table B and C and COALESCE some value (or values? you did not provide any column list or what your desired output is so I assume there is just one content containing column in table B as well as in C)
For selecting from one column in those tables I would do the following
SELECT
COALESCE(B.yourcontentcolumn, C.yourcontentcolumn, <defaultvalueifnull>)
FROM A
LEFT JOIN B ON B.id = A.b_id
LEFT JOIN C ON C.id = A.c_id
I am planning to create a website similar to IMDB.com. To reduce execution time I am using the following structure. Is it okay for faster working?
Table - 1
Id Movie_name description
1 name one some description
2 name two some description
3 name three some description
Table 2
id actorname
1 name 1
2 name 2
3 name 3
4 name 4
Table 3
id movieid actorid
1 1 1
2 1 2
3 1 3
4 1 9
5 2 6
6 2 5
7 2 8
8 2 1
When I want to list actors in a movie program will retrieve actors ids from table 3 and find respective names from table 2 (using single query). When I want to list the movies of a actor it will retrieve movie ids from table 3 and find respective names from first table. Will it work properly? Any other ideas?
This will give all actors in a specified movie,
SELECT c.ID, c.actorName
FROM table1 a
INNER JOIN table3 b
ON a.ID = b.movieID
INNER JOIN table2 c
ON b.actorid = c.ID
WHERE a.ID = 1
This one will give all movies for a specified actor
SELECT a.*
FROM table1 a
INNER JOIN table3 b
ON a.ID = b.movieID
INNER JOIN table2 c
ON b.actorid = c.ID
WHERE c.ID = 1
SQLFiddle Demo (both queries)
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
UPDATE 1
This is called Relational Division
SELECT a.ID, a.Movie_Name
FROM table1 a
INNER JOIN table3 b
ON a.ID = b.movieID
INNER JOIN table2 c
ON b.actorid = c.ID
WHERE c.ID IN (1, 2, 3)
GROUP BY a.ID, a.Movie_Name
HAVING COUNT(DISTINCT c.ID) = 3
SQL of Relational Division
I suggest that you modify table3 by taking away the id field. Use the movieid and actorid together as your primary key. You might want to add other fields to this table such as name of character and order of appearance as suggested in the comment by Jermaine Xu.