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.
Related
I want to select DISTINCT(p.ptype) at the same time I also want to get the c.category if p.ptype is not in the set of c.ptype
Database Table: p
id ptype
1 Shirts
2 Cups
3 Shirts
4 Mugs
Database Table: c
id category ptype
1 Test Pants, Shirts, TShirts
2 Test1 Cups, Mats, Rugs
The SQL command I tried is as follows
SELECT DISTINCT(p.ptype), IF(FIND_IN_SET(p.ptype, c.ptype), c.category,'') as category
FROM p, c
This outputs p.ptype which are in set twice. One time with a blank c.category field and one with filled c.category.
However the desired output is as follows
ptype category
Shirts Test
Cups Test1
Mugs
Try doing an explicit LEFT JOIN on the ptype from the p table being present in the CSV list in the c table:
SELECT DISTINCT p.ptype, COALESCE(c.category, '') AS category
FROM p
LEFT JOIN c
ON FIND_IN_SET(p.ptype, c.ptype) > 0
In your original query, were doing a cross join. This generates all possible combinations between the records of the two tables. It would be difficult to arrive the correct answer using a cross join, so a left join is preferable.
Demo here:
SQLFiddle
I have this Table (tblExample):
ID U_ID Title Desc Cat SubCat Country Date
----------------------------------------------------------------------------
1 2 Title1 Desc1 Orange Blue England 12/05/2015
2 3 Title2 Desc2 Orange Blue England 12/05/2015
3 2 Title3 Desc2 Orange Blue England 12/05/2015
I then have another table (tblRating):
ID U_ID rating
------------------
1 2 4
2 2 2
3 2 4
If I do an SQL statement like:
select e.*, r.*
from tblExample e
inner join tblRating r on e.U_ID = r.U_ID
The result I get is just the details of U_ID = 2, but I want to still show U_ID = 3, this is the user that has no record in tblRating. How can I do this? I tried left join but did not work.
Replace the inner join with a left join. This will give you all the relevant rows from tblExample and tblRating or nulls where tblRating does have a matching rows:
SELECT e.*, r.*
FROM tblExample e
LEFT JOIN tblRating r ON e.U_ID = r.U_ID
This is because of Join issue, when you perform INNER JOIN only the matching records from both table returns.
If you want to get all the records from first table and only the matching records from the second table then you need to perform LEFT JOIN.
select
first.*,
second.*
from tblExample first
LEFT JOIN tblRating second on first.U_ID = second.U_ID
For the second table it will return NULL in case of not matching conditions.
You can also refer this question about difference between JOINS,
I have two tables category and adverts, i need to select all categories and the number of adverts it has in the adverts table that has at least count greater than zero
the category table
cat_id | Name
----------------
1 | Toys
2 | fashion
3 | electronics
The adverts table
cat_id | title
----------------
1 | a
2 | b
2 | c
1 | d
2 | e
what i expect
cat_id | count | Name
-----------------------
1 |2 | a
2 |3 | b
The query i tried
Select
c.name, c.cat_id,c.parent_id, #count:= (Select Count(av.cat_id) From adsview av Where av.cat_id = c.cat_id)
from
category c WHERE #count > 0
i am getting and empty result, what am i doing wrong?
If you want to make sure that the cat_id from category table are in adverts table you need to join as
select
c.cat_id,
c.Name,
count(a.cat_id) as `count`
from category c
join adverts a on a.cat_id = c.cat_id
group by c.cat_id ;
select cat_id, count(*)
from adverts
group by cat_id;
So the mySQL query engine will grab every single row from the adverts table, it'll put them into neat piles where all rows in the pile have the same category, it'll count the number of rows in each pile, and then it'll return to you a result row for each pile with the pile's id and the number of rows.
Now lets add something: we want to also get the category's name. So we indicate that in the select clause, and add a join to the from clause. The join says "for every row in table a, consider it alongside every row in table b. if some condition holds, put this combined row into the from set". You can see that joins are actually quite slow in SQL (relatively).
select c.cat_id, count(*) as count, c.name
from adverts as a join categories as c on a.cat_id = c.cat_id
group by c.cat_id;
Note also that I've aliased the tables as a and c respectively, so as to remove the ambiguity over the column name cat_id (otherwise the mySQL query engine may get confused).
You can try this, mate:
SELECT
c.cat_id,
COUNT(a.cat_id) AS count,
a.title
FROM
category c
LEFT JOIN adverts a ON a.cat_id = c.cat_id
GROUP BY
c.cat_id
HAVING
count > 0;
or this:
SELECT
c.cat_id,
COUNT(a.cat_id) AS count,
a.title
FROM
category c
INNER JOIN adverts a ON a.cat_id = c.cat_id
GROUP BY
c.cat_id;
You have to use group by function like below
select cat_id, count(*) as count
from adverts
group by cat_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.
I have to select data from two tables with following criteria,
lets say there are two tables as,,
Table one
id | itemName | Quantity | companyName
1 bread 25 the Baker pvt ltd
2 butter 30 green famers
Table two
id | itemName | itemPrice
1 bread 30.50
6 jam 80.25
what I need is,
select items out of two tables which their ids are matching and the quantities of them should be multiplied by the unit price if ids are matching. The rows which don't have matching ids should be selected but their quantities should not multiplied.
SELECT o.id, o.itemName, o.companyName, o.Quantity * IFNULL(t.itemPrice, 1) total
FROM one o
LEFT JOIN two t
ON o.id = t.id
Something like this should work ...
Select a.id, a.itemName, a.companyName, a.Quantity * IFNULL(b.itemPrice,1) As total
From table1 as a
Left Join table2 as b on a.id = b.id