How to retrieve intersection from three or four tables in Mysql - mysql

I have tables that contain common column.
A : car, banana, monkey
B : banana, dragon, snail
C : shoes, socks, banana
As you can see, column banana is the common column. Same name, same data type, (int).
And I want to do some search work span these table.
For example,
In A table, I want to find the rows that contains keyword 'Toyota' in column 'car'.
In B table, keyword 'evil snail' in column 'snail'
....
Like this.
Then, I'd like to retrieve the value of banana fields through two methods :
From the found rows of all tables
banana that can be found in found row in all tables.
So despite I can't even sketch about solution, two sql line is needed...
I kept think almost eight hours to solve this problem but only headache is get worsen..
I wonder someone could help this out...

To find all the A that contains the key word 'Toyota' in 'car' do:
SELECT * FROM A WHERE car like '%Toyota%';
Same for B and C. You should notice that the like is use in the case where we are checking if the column contains the value. To make an exact match you should use the equal to sign e.g. car='Toyota'.
For your second query type you want a result which is a dis-junctive in nature. So you should query each table and unite the result like:
SELECT a.banana FROM A a where a.banana=[VALUE]
UNION
SELECT b.banana FROM B b where b.banana=[VALUE]
UNION
SELECT c.banana FROM C c where c.banana=[VALUE];

Related

How to create this dynamic PIVOT view where the price of 3 fruits are not changing simultaneously?

The Initial Data View, we have
Lets consider this table as Table A.
Here we can see that there are 3 markets: A,B,C and there are 3 fruits: Apple, Banana, Strawberry.
There is Start Date and End Date for each of the fruits of each market. These dates imply that the price of the fruit is applicable b/w that interval of dates. If the End Date is empty that means the rate is still applicable.
Now from this table, we want a transposed view of the table. And the final output we want is:
The View, we want
Lets consider this table as Table B.
This looks like a simple PIVOT function in SQL to transpose the rates and we tried that. But the result we are getting is not expected. The output is coming out to be:
The Output, we are getting
Lets consider this table as Table C.
The problem is that as in markets A and B, the rates of the 3 fruits are not simultaneously changing, the PIVOT function is not giving expected results.
We have tried the simple pivot function on the Table A:
The code we are using for the PIVOT-
PIVOT(MAX(PRICE/kg)) FOR FRUIT IN
('Apple_Price', 'Banana_Price', 'Strawberry_Price')
AS (MARKET, START_DATE, END_DATE, Apple_Price, Banana_Price, Strawberry_Price)
We have also tried another method where we tried to join 3 times separately Table A. But it is also not working.

Join 3 Distinct Tables in MySQL with no Common or Linked Column

I Have Three Distinct Tables in Mysql which have no column in common, I want to access one column from each table & show all of them combined elsewhere.
Table Details are
Table_1 = screen, Column Name : S_Id
Table_2 = Movie, Column Name : M_Code
Table_3 = showdetails, Column Name : Show_Id
There are many more columns in each table but i have mentioned what i want to access.I Have tried the following code but this returns only column names as output & no column data is received in output.I am a beginner in Databases so please help me with this.
SELECT * FROM screen
JOIN movie ON movie.M_Code = screen.S_Id
JOIN showdetails ON showdetails.Show_Id = screen.S_Id;
you can create 3 individual select statements and link them on a hard coded artificial key
select a, b, c, d, e, f from (
(select a, b, c, 1 as key from atable) aa
inner join
(select d, e, f, 1 as key from btabke) bb
on aa.key = bb.key
something along those lines
essentially, each select statement becomes its own table, selecting only those rows which you want to be linked to the other select based tables. The artificial key is a simple way of linking them together since you have no other means of doing so
I am not exactly sure I understand what you want to achieve. Are those tables somehow related to each other, e. g. has every movie a screen on which it is shown on? If so, you had to join like this:
SELECT * FROM screen JOIN movie ON movie.S_Id = screen.S_Id
Imagine your tables are like the following:
Screen
S_Id| name
-----------
1 | Main Screen
2 | Screen 2
3 | Little Screen
Table
M_Code| Name
-------------
1 | Find Nemo
2 | Odyssey in Space
3 | Lord of the Rings
Your join statement would join the IDs as they are, in this case Find Nemo to Main Screen, Odyssey in Space to Screen 2 and LOTR to the Little Screen. Thats probably not what you wanted to achieve, so you have to use or add a column which links those data rows to each other.
If you instead want to get every possible combination, you can use Constantins answer, but I think if you have many datasets this could get very slow. Instead you could retrieve all datasets of every table and combine only those which make sense in your program.

Selecting values where the first 6 characters match

I'm trying to pull a list of IDs from a table Company where the first 6 characters of the ID are the same. The way our application creates a company ID is it takes the first 3 characters of the company name and the first 3 characters of the City. Beceause of that, overtime we have company IDs with the same first 6 characters, followed by a sequential number...
I was thinking using something using LIKE
Select companyID, companyName from Company Where
substring(companyID,1,6)+'%' like substring(companyID,1,6)+'%'
Basically i'm trying to get all company IDs where the first 6 characters match; The result set should show the just the top company ID ( The first 1 created) and the company name. I'm not expecting a tone of results, so i can then use the IDs returned to find the IDs below it.
I'm thinking it could maybe also be done using HAVING, where the count of IDs with the same first 6 characters are the same HAVING Count(*)>1??
Not really sure what the syntax would be...
SELECT distinct c1.CompanyID, c1.CompanyName, c2.CompanyID, c2.CompanyName
FROM dbo.Company c1
JOIN dbo.Company c2
ON SUBSTRING(c1.CompanyName,1,6) = SUBSTRING(c2.CompanyName,1,6)
AND c1.CompanyID < c2.CompanyID
order by c1.CompanyName, c2.CompanyName
SELECT c1.CompanyID, c1.CompanyName, c2.CompanyID, c2.CompanyName
FROM dbo.Company c1
INNER JOIN dbo.Company c2
ON SUBSTRING(c1.CompanyName,1,6) + '%' LIKE SUBSTRING(c2.CompanyName,1,6) + '%'
AND c1.CompanyID <> c2.CompanyID
If this is something that you envision doing frequently, I'd add a computed column to the table that has a definition of substring(CompanyName, 1, 6). You can then index it and make this efficient. As it is, it will have to scan all the entries and calculate the substring on the fly. With the computed column, you amortize the substring calculation up front and at least have a chance at an efficient query.
After trying to use Blam's script, i made a few slight changes and got some better results. His script was returning more results than rows in the table and it was pretty slow; think it's because of the company_name column. I got rid of it and wrote it like this:
select distinct c1.cmp_id, count(substring(c2.cmp_id,1,6)) as TotalCount
from company c1
join company c2 on substring(c1.cmp_id,1,6)=substring(c2.cmp_id,1,6)
group by c1.cmp_id
order by c1.cmp_id asc
This still returns all the table records, but atleast i can see the total count when the first 6 characters are listed more than once. Also, it ran in only 1 second so that's also a plus. Thank again for you input guys, always appreciated!

SQL Joins - Why does this simple join work, despite the syntax making no sense?

I've read numerous tutorials and graphical representations of MySQL joins, and they still don't make sense to me.
I'm trying to type my own now, and they are working, but I just don't see how they're working.
Take this set of tables
images squares
---------------------------- ----------------------------------
image_id | name | square_id square_id | latitude | longitude
---------------------------- ----------------------------------
1 someImg 14 1 42.333 24.232
2 newImg 3 2 38.322 49.2320
3 blandImg 76 3 11.2345 99.4323
... ...
n n
This is a one to many relationship - one square can have many images, but an image can only have one square.
Now I run this simple join, but I'm not understanding the syntax of it at all...
SELECT images.image_id
FROM squares
LEFT JOIN images ON images.square_id=squares.square_id
WHERE images.square_id=711464;
Now, this actually works, which amazes me. It brings up a list of images within the square range.
But I'm having a hard time understanding the ON syntax.
What does ON do exactly?
Does it show how the two tables are related?
Mainly however, SELECT images.image_id FROM squares, makes the least sense.
How can I select a field in one table but FROM another?
Let's start with the FROM clause, which in it's entirety is:
FROM squares LEFT JOIN images ON images.square_id=squares.square_id
(it's not just FROM squares).
This defines the source of your data. You specify both tables, squares and images so they are both sources for the data that the query will work on.
Next, you use the on syntax to explain how this tables are related to one another. images.square_id=squares.square_id means: consider a row in the images table related to a row in the squares table if and only if the value of the field square_id of the images row is equal to the value of the field square_id of the squares table. At this moment, each row of the result is a combination of a row from the images table and a row from the squares table (I'll ignore the LEFT JOIN at the moment).
Next, you have the WHERE clause
WHERE images.square_id=711464
This means, from the rows that are in result set, just get those where the value of the square_id field, in that part of the result row that came from the images table, is exactly 711464.
And last comes the SELECT part.
SELECT images.image_id
This means, from the rows that are in the result set (a combination of a square row and a images row), take just the field image_id that is from the images table.
You should read the query as such:
SELECT images.image_id FROM
squares LEFT JOIN images
ON images.square_id=squares.square_id
WHERE
images.square_id=711464
So you first join the squares table with the images table, combining entries in images which have the same square_id as in the squares table. So, the ON syntax is actually specifying the condition on which the two tables should be joined.
Then, you do a filter using WHERE, which will take the entries with square_id=711464
Note that by the time you do the SELECT, you already joined the two tables, which will have the combined fields:
images
--------------------------------------------------
square_id | latitude | longitude | image_id | name
--------------------------------------------------
So, you can select the square_id from the resulting table.
It is more like :
SELECT images.image_id FROM (squares LEFT JOIN images ON images.square_id=squares.square_id WHERE images.square_id=711464)
So you don't select a field from another table - it is more like you create a new temporary table from the statement in brackets (actually having columns from multiple tables) and then perform SELECT on this table.
And yes, ON defines how the tables are related (for instance with foreign key)
SELECT [COLUMNS] --First Line Of Code - say it as 1
FROM --Second Line Of Code -- say it as 2
[Table1] Join [table2] On [Criteria] --say it as 3
Where [Some More Criteria] --Say it as 4
Whenever a
Select Column From
is done it gets the data from 3 which is collection of multiple table or single table.
Once the data is loaded it Executes the where criteria for filtering the data.
After data filtration Select statement will be Executed.
In your case:
Left Join will execute and generate table with 6 columns. based on Join Criteria. Than Where criteria will be executed to filter the data.
Select statement execution will takes place only after that.
Regarding using the Table Name as prefix is to avoid the conflict in Column Name.
P.S : This is for your understanding, actually the data load doesn't happen. To understand exactly how queries are executed you need to understand DB Engine.
As Of Now,Write query and leave the DB Engine for planning.
With Experience Comes The Knowledge.
Happy Coding

Query multiple rows that leads to one row in other table

I'm a noob at making mySQL queries so I couldn't get my work done. I hope you guys know the answer to my question.
I want to make options to my products. Like if you have a black t-shirt, with a tanktop model and diamonds on it. You must have the black t-shirt tanktop model and diamonds row. I want to make it like this:
table: product_option
--------------------------------
product_option_id name product_combination_id
1 Black 1
2 Diamond 1
3 Tanktop 1
4 Option 2
5 Option 2
table: product_combination
--------------------------------
product_combination_id name
1 Black tanktop with diamonds
So my question is. Is it possible to query the product_options and get an product_combination row out of it?
I hope you guys know the answer to my question! Thank you for your time :)
EDIT:
I think my question was too general and I want to ask it more specific.
Let's say. I have a shop with clothes. I have a product (let's say an T-shirt). And there are a couple of options to choose from.
Like this:
Color:
- Black
- Red
- Orange
Size
- Large
- Xtra Large
- Medium
- Small
Accessoire:
- Diamonds
- Printed
- Swarovski
Let's say I want to buy the Black / Xtra Large T-shirt with Diamonds on it. Then the product_combination must be Black/Large/Diamonds Row. I think I need an Foreign table with a Many to Many relation. Like product_combination_option table with the columns:
product_combination_option
- product_combination_option_id
- product_combination_id
- product_option_id
But then again. How can I query when someone chooses Black / Xtra Large with Diamonds and find which product_combination it is.
I hope I'm a bit clearer now. Sorry that I updated my question so late! I appreciate all your answers very much!
I think what you are looking for is joining your tables, so that you can pick up a combination based on the product you have.
So, for that, a query can be
Select *
from product_option inner join product_combination
using(product_combination_id);
This joins the 2 tables. so you can replace the * with the list of attributes you want to display/fetch.
If you mean you want to pass a list of options to the query and get a list of matching product_combination entries, then here's one way:
SELECT *
FROM product_combination
WHERE product_combination_id IN (
SELECT product_combination
FROM product_option
WHERE name IN ('option1', 'option2', 'option3')
GROUP BY product_combination
HAVING COUNT(*) = 3
);
The subquery returns a set of product_combination values that have all three options requested. The COUNT(*) = 3 condition assumes that a single product_combination value cannot have duplicate name values associated with it. (Which is only natural, but in case your table doesn't have the corresponding restriction, you could replace COUNT(*) with COUNT(DISTINCT name) to make sure a group being returned contains all three options specified and not just three rows of which some contain identical options.)
Of course, if the number of options queried isn't fixed, you'll need to build the query dynamically because of the IN predicate, because it is not parametrisable (in terms of the number of items). However, you could try using a temporary rowset instead of a hardcoded list. The table would be populated before running the query in question, which in this case would be modified to this effect:
SELECT *
FROM product_combination
WHERE product_combination_id IN (
SELECT product_combination
FROM product_option
WHERE name IN (SELECT option_name FROM requested_options)
GROUP BY product_combination
HAVING COUNT(*) = (SELECT COUNT(*) FROM requested_options)
);
In the above query, requested_options is the name of the temporary storage (possibly a temporary table, but I'm not sure if MySQL allows you to access one that was created and and populated beforehand in a different query), and option_name is its column containing the options being requested.