How to create a combination table from a single table MySQL? - mysql

So I have this following table options lets say it contains three columns :
--------------------------
--------- options --------
--------------------------
id | name | category
--------------------------
1 | blue | 1
2 | red | 1
3 | a | 2
4 | b | 2
5 | c | 2
6 | 99 | 3
--------------------------
Now, I already have the following query to create a table containing three columns as a combination from table above :
SELECT T1.name, T2. name, T3.name
FROM (options T1 JOIN options T2 ON (T1.name > T2.name AND T1.category != T2.category))
LEFT JOIN options T3
ON (T3.name < T2.name AND T3.name < T1.name AND T3.category != T1.category AND T3.category != T2.category);
The results from running above query will return the following table (which is incorrect):
--------------------------
------ combinations ------
--------------------------
name | name | name
--------------------------
blue | a | 99
red | a | 99
blue | b | 99
red | b | 99
blue | c | 99
red | c | 99
red | 99 | NULL
blue | 99 | NULL
a | 99 | NULL
b | 99 | NULL
c | 99 | NULL
--------------------------
The resulting table should look as follows:
--------------------------
------ combinations ------
--------------------------
name | name | name
--------------------------
blue | a | 99
red | a | 99
blue | b | 99
red | b | 99
blue | c | 99
red | c | 99
--------------------------
The problem is whenever there is 3 different categories in the options the combination will also return the third name column including NULL values, and we don't want that.
I want the resulting combinations table to always have 3 column, and if there is only one category only populates the first column in the combinations table (the other columns should be null in this case), if there is two the first two columns as combinations (3rd column will be null), and if its three, all three columns have to have values respective to the options table (no null values).

Use cross join:
select *
from (select name
from options
where category = 1
) n1 cross join
(select name
from options
where category = 2
) n2 cross join
(select name
from options
where category = 3
) n3

Related

mysql linked tables, return null if not present in connecting table

I have 2 tables that have a many-to-many relation, using a 3rd table.
Table 1 colors:
____________
id | color |
____________
1 | red |
2 | blue |
3 | yellow |
4 | orange |
5 | green |
table 2 content: (Table content is not really relevant for the query, I add it for completeness.)
id | itemname
1 | item1
2 | item2
3 | item3
...
table 3 is the connecting table colors_content
id | content_id | color_id
1 | 1 | 1
2 | 1 | 2
3 | 1 | 5
4 | 2 | 1
5 | 3 | 1
6 | 4 | 4
I want to return all colors + a way to figure out which ones are already linked to the content_id I am querying, so as an example, so for item.id=1 the result should be:
colors.id | colors.color | colors_content.content_id
1 | red | 1 (this can be anything, like a boolean)
2 | blue | 1
3 | yellow | null
4 | orange | null
5 | green | 1
again: it is a many-to-many relation, I need to output exactly 1 of each color, with a way to know if the queries item is already linked to it.
I have tried joining in different ways but I can not seem to find the correct syntax that includes the null values for unlinked colors.
SELECT c.* FROM `colors` c left join colors_content cc on cc.color_id=c.id where cc.content_id=1
only returns the 3 linked colors for item 1, not the 2 others.
edit:
This quite convoluted query seems to do the trick (although I am unclear why the group statement will not randomly choose between the queried id and the 0 value), but I must be missing a more obvious solution:
select * from ( SELECT c.id , c.color, cc.content_id as present FROM colors c JOIN colors_content cc ON c.id=cc.color_id WHERE cc.content_id=7 UNION select id , color, 0 as present from colors) as resulttable group by color
Move the check for the content_id in the ON clause and then check if the color_id of colors_content is NULL.
SELECT c.id,
c.color,
cc.colorid IS NULL exists_for_content_id
FROM colors c
LEFT JOIN colors_content cc
ON cc.color_id = c.id
AND cc.content_id = 1;
(This assumes that (colors.id), (content.id) and (colors_content.content_id, colors_content.color_id) are not nullable and unique.)

Show row on mysql with this case

I have rows in my table like this
+----+-------+--------+--------------+---------------------+
| id | cid | number | value | date |
+----+-------+--------+--------------+---------------------+
| 2 | 1 | 55 | two to one | 2020-04-19 11:25:52 |
| 2 | 9 | 56 | two to nine | 2020-04-19 11:26:04 |
| 1 | 2 | 57 | one to two | 2020-04-19 11:27:02 |
| 9 | 2 | 58 | nine to two | 2020-04-19 11:28:01 |
+----+-------+--------+--------------+---------------------+
What is the sql code to show like this
+----+-------+--------+--------------+---------------------+
| id | cid | number | value | date |
+----+-------+--------+--------------+---------------------+
| 1 | 2 | 57 | one to two | 2020-04-19 11:27:02 |
| 9 | 2 | 58 | nine to two | 2020-04-19 11:28:01 |
+----+-------+--------+--------------+---------------------+
That is mean just show latest row and make the id with cid is same like id=1-cid=2 is same with id=2-cid=1. Anybody please help and i hope you are know what i mean. Thank you so much
You can use a derived table to generate a list of latest date values for each combination of id and cid values, using LEAST and GREATEST to map (for example) (1, 2) to (2, 1). This can then be JOINed to the original table to get the data for latest date:
SELECT t1.id, t1.cid, t1.number, t1.value, t1.date
FROM data t1
JOIN (
SELECT LEAST(id, cid) AS l_id,
GREATEST(id, cid) AS g_id,
MAX(date) AS max_date
FROM data
GROUP BY l_id, g_id
) t2 ON t2.max_date = t1.date
AND (t2.l_id = t1.id AND t2.g_id = t1.cid OR
t2.l_id = t1.cid AND t2.g_id = t1.id)
Output (for your sample data):
id cid number value date
1 2 57 one to two 2020-04-19T11:27:02Z
9 2 58 nine to two 2020-04-19T11:28:01Z
Demo on SQLFiddle

SQL Query to CAST and SUM columns in two different Tables having Multiple Entries

Need help in Building a Query which can select a Item and sum up its QTY which is in 2 different Tables.
Example Scenario:
Table 1:
ID | ITEM_NAME | QTY |
1 | Item_Desc1 | 0 |
2 | Item_Desc2 | 2 |
3 | Item_Desc3 | 4 |
4 | Item_Desc4 | 0 |
Table 2:
ID | ITEM_ID | BATCHNO | QTY
1 | 1 | B1 | 100
2 | 1 | B2 | 100
3 | 2 | B3 | 0
4 | 3 | B2 | 100
5 | 4 | B2 | 200
6 | 4 | B3 | 100
Need a Query to show in a Data grid Table as follows:
ID | Item_Name | QTY
1 | Item_Desc1 | 200
2 | Item_Desc2 | 2
3 | Item_Desc3 | 104
4 | Item_Desc4 | 300
Note:
This Query should be useful to run a Search query using 'LIKE' operator by using which User can search for Items Needed
SAMPLE Image of My APPLICATION to Run Search query using Table 1 and Table 2
SAMPLE Image of My APPLICATION DATABASE - TABLE2
SAMPLE Image of My APPLICATION DATABASE - TABLE1
To get sum from 2 table you can use following query
select a.ID, a.ITEM_NAME, a.QTY + coalesce(b.QTY,0)
from Table1 a
left join (
select ITEM_ID,sum(QTY) QTY
from Table2
group by ITEM_ID
) b on a.ID = b.ITEM_ID
Demo
Try the following query
select tbl1.id as ID,tbl1.Item_Name, tbl.qty+sum(tbl2.qty) as QTY
from table1 as tbl1 JOIN table2 as tbl2
ON tbl1.id = tbl2.id group by tbl2.item_id

Extracting record from table skip record of other table

Having two tables
1. Parent Users
2. Child Users
Child User table also has records of Parent Users.
I want an output of All Childs only.
The better way to take one more column in child User with flag ( 1 for parant user, 0 for child user ) like:
child users
-------------------------------------
| id | name | by_id | flag |
-------------------------------------
| 1 | x | 1 | 1 |
| 2 | a | 1 | 0 |
| 3 | b | 1 | 0 |
| 4 | z | 3 | 1 |
| 5 | c | 3 | 0 |
| 6 | y | 2 | 1 |
| 7 | d | 2 | 0 |
| 8 | e | 1 | 0 |
To get all child entries:
SELECT id, name FROM child_users WHERE flag = 0;
I prefer to solve this using a LEFT JOIN of the child table against the parent table:
SELECT t1.*
FROM ChildUsers t1
LEFT JOIN ParentUsers t2
ON t1.by_id = t2.id AND
t1.name = t2.name
WHERE t2.name IS NULL
The trick here is the WHERE clause WHERE t2.name IS NULL, which will discard any records which correspond to parents.
As #SHAZ pointed out in his comment, the only way to identify a child entry as being a potential parent is by using the name field. In the event that a parent and child who are different happen to have the same, then the child could be incorrectly filtered out from the result set.
Demo Here:
SQLFiddle
This one:
SELECT a.id, a.name,a.by_id from
(select id,name,by_id from tbl_child) as a
left JOIN
(select id, name from tbl_parent)as b
on a.name = b.name where b.name is null
It return an output as you need.

Mysql: return 0 when result 1 row in a table, other table result is 2 rows

How to display result
Temp | Order | Payment
A | 5 | 3
A | 4 | 0
B | 2 | 2
B | 0 | 3
C | 3 | 0
with: first_table:
Name | Description
A | Description A
B | Description B
C | Description C
second_table:
Name | order
A | 5
A | 4
B | 2
C | 3
third_table:
Name | Payment
A | 3
B | 2
B | 3
Meaning:
there are 2 order (value: 4,5) with Name=A.
there is 1 order (value: 3) with Name = A
And result I want to display:
Name | Order | Payment
A | 4 | 3 |
A | 5 | 0 |
Any help me?
You need to use JOIN.
From your example there is no Payment for order A5 so you should use LEFT JOIN which will result in Payment being NULL for that row (A5). LEFT JOIN basically means "select rows from first table and if there is no match in second table, put NULL".
Simply do a LEFT JOIN on second_table and third_table on field Name where Name=a. It's a very basic example so I won't give you the exact query, you should learn it by yourself.