Trying to figure out if it is possible to create a query where you join tables, table one is smaller than table two, table two has multiple references matching table one entries, the query would output a joining where table one length is preserved but you just add more columns. Not sure if that makes sense so here is a example of what I am after
Table One Table two
+-----------------------------+ +-----------------------------+
| id | english | definition | | id | word_id | sentence |
+-----------------------------+ +-----------------------------+
|1 | A1 | blah | |1 | 1 | blahblah1 |
|2 | B4 | blah2 | |2 | 1 | blahblah2 |
+-----------------------------+ |3 | 1 | blahblah3 |
|4 | 2 | blahblah4 |
|5 | 2 | blahblah5 |
+-----------------------------+
********* Query should return something like *****************
+----------------------------------------------------------------+
| id | english | definition | sentence | sentence2 | sentence3 |
+----------------------------------------------------------------+
|1 | A1 | blah | blahblah1| blahblah2| blahblah3 |
|2 | B4 | blah2 | blahblah4| blahblah5| |
+----------------------------------------------------------------+
My Current query looks like this and results in:
$query = "SELECT * FROM T1 INNER JOIN T2 ON T1.id = T2.word_id";
Resulting in:
+----------------------------------------+
| id | english | definition | sentence |
+----------------------------------------+
|1 | A1 | blah | blahblah1|
|1 | A1 | blah | blahblah2|
|1 | A1 | blah | blahblah3|
|2 | B4 | blah2 | blahblah4|
|2 | B4 | blah2 | blahblah5|
+----------------------------------------+
I am working with PHP and MySql.
UPDATE!!
Staying with my original query and manipulating the results with PHP getting good performance too. Let me know if you need me to post my code.
You might be looking for GROUP_CONCAT()
SELECT T1.id, T1.english,T1.definition,
GROUP_CONCAT(T2.sentence ORDER BY T2.ID SEPARATOR '|')
FROM Table1 T1 INNER JOIN Table2 T2 ON T1.id = T2.word_id
Group by word_id
Sample fiddle
The answer is NO. Simply because there's unknown number of columns (say, if you add one more sentence to the top word you could be adding one more column to the result set) and each column is not well defined ( Why blahblah4 should be in column sentence instead of sentence2 ?)
IMO, SQL is used to tell what you want to get, but in this case, SQL is unable to tell exactly what you want.
Even if this can be done ( I would love to learn ), I believe the complexity offsets any benefit and handling this in PHP is a better option.
Related
I need some help with MySQL/PHP. Which is the faster execution in code point of view.
I have below tables
1. table_content
--------------------------------
id | section | content_id
--------------------------------
1 | A | 15
2 | B | 25
3 | A | 9
--------------------------------
2. table_a
--------------------------------
id | name | message
--------------------------------
9 | John | Hello Everyone
15 | Smita | Hi
17 | Vinayak | How are you?
--------------------------------
3. table_b
--------------------------------
id | label | description
--------------------------------
1 | David | D1
5 | Alia | D2
25 | Vinay | D3
--------------------------------
I have above table structure. For me table_content is main table. I want below output through MySQL/PHP [As array and section as key].
Output
------------------------------------------------
id | section | name | message
------------------------------------------------
1 | A | Smita | Hi
2 | B | Vinay | D3
3 | A | John | Hello Everyone
------------------------------------------------
I have tried with SWITCH case. But not getting exact output.
Which is the better performance and fast execution? with MySQL or PHP. I have thousands of data like this.
Please help me to solve this problem.
Should be acheved via a JOIN.
Also ensure you have configured appropriater indexing, otherwise it will perform badly when you get to a large volume of data.
As i posted in my comment you need to Join the both tables, which must be UNION
SELECT tc.`id`, tc. `section` ,t1.`message`
FROM table_content tc JOIN (SELECT `id`, `name`, `message` FROM table_a UNION SELECT `id`, `label`, `description` FROM table_b) t1
ON tc.`content_id` = t1.`id`
id | section | message
-: | :------ | :-------------
1 | A | Hi
2 | B | D3
3 | A | Hello Everyone
db<>fiddle here
My question is: Can I do this?
I try many things, some of them are:
Search 1
Search 2
Search 3
Search 4
I need all the info form Table A, and sometimes I need to join this table with Table B. My problem is that when I join both tables, if an specific parameter in Table A is not in Table B just give me the records when the specific parameter are, but I want all the records.
Table A
|--------------------------------|
| Table A |
|-------------------|------------|
| id_table_A | name | id_table_B |
|------------|------|------------|
| 1 | Joe | 1 |
|------------|------|------------|
| 2 | Ben | |
|------------|------|------------|
| 3 | Lya | |
|------------|------|------------|
| 4 | luis | 2 |
|------------|------|------------|
Table B
|----------------------|
| Table B |
|----------------------|
| id_table_B | Elements|
|------------|---------|
| 1 | Car |
|------------|---------|
| 2 | Byke |
|------------|---------|
| 3 | Moto |
|------------|---------|
What I want to show in my View is this:
|------------|------|------------|
| id_table_A | name | Elements |
|------------|------|------------|
| 1 | Joe | Car |
|------------|------|------------|
| 2 | Ben | |
|------------|------|------------|
| 3 | Lya | |
|------------|------|------------|
| 4 | luis | Byke |
|------------|------|------------|
My model
In my model this is what I tried:
"SELECT * FROM table_A, table_B where table_A.id_table_B = table_B.id_table_B"
But this query only show me data 1 and 4.
This can be done or not?
Thanks in advance.
You can use left join
SELECT *
FROM table_A
left join table_B on table_A.id_table_B = table_B.id_table_B
Left join is used when the keys between tables may not always match. In this case, the left join retrieves the correct match where it's possible and the values become NULL when not possible.
SQL LEFT JOIN Documentation
You need an explicit LEFT JOIN as opposed to the implicit INNER JOIN that is used when you simply list the tables like that. https://www.w3schools.com/sql/sql_join_left.asp
I have a table that puts multiple values into a single value in MySQL, separated by linebreaks. Like this:
+------------+-------------+
| Company | Products |
| (VARCHAR) | (TEXT) |
+------------+-------------+
| Acme Corp | Medicine |
| | Food |
| | Phones |
+------------+-------------+
| Ajax Corp | TVs |
| | Phones |
| | Pianos |
+------------+-------------+
I can't do anything about the table structure. Now I need a query that will return this table:
+==========+
| Products |
+==========+
| Food |
+----------+
| Medicine |
+----------+
| Phones |
+----------+
| Pianos |
+----------+
| TVs |
+----------+
I prefer a pure MySQL approach, but a solution with PHP is also OK for me.
There are no handy ways to split a field with MySQL. (Check the comments in the MySQL documentation). So, the best method seems to obtain all the product records with a simple:
SELECT Products FROM YourTable
And after in you php code:
$products = array_merge($products, explode("\n", $record));
for each record.
This will work for 3 products maximum,for more it needs a bit of tinkering
CREATE TABLE t
(
company varchar(20),
products text
);
INSERT INTO t
VALUES
('Acme', 'Medicine,Food,Phones'),
('ajax', 'TVs,Phones,Pianos');
SELECT SUBSTRING_INDEX(Products,',',1) FROM t
UNION
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(Products,','),',',2),',',-1) FROM t
UNION
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(Products,','),',',3),',',-1) FROM t
WHERE SUBSTRING_INDEX(Products,',',1)<>''
AND SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(Products,','),',',2),',',-1) <>''
AND SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(Products,','),',',3),',',-1)<>''
Results
Medicine
TVs
Food
Phones
Pianos
I have these tables:
Table 'Data':
| Customer | Category | Brand | Market | A | B |
|==========|==========|=======|========|===|===|
| Bill | 5 | 4 |1 |2 |9 |
| Bill | 5 | 4 |1 |6 |15 |
| Bill | 5 | 4 |1 |1 |30 |
| Greg | 7 | 9 |3 |5 |1 |
| Amy | 9 | 2 |1 |1 |8 |
Table 'Customer':
| Cust | Mkt | SubMkt |
|======|=====|========|
| Bill | 1 | NY |
| Bill | 2 | Arizona|
| Bill | 3 | Cali |
| Greg | 1 | Ohio |
| Amy | 1 | Texas |
Table 'Sort':
| SubMarket | SortBy |
|===========|========|
| Cali | A |
| Ohio | B |
| Arizona | A |
| NY | A |
I need to select all from 'Data' ordered by a few different columns and then either A or B depending on what 2 other tables say.
SELECT *
FROM Data
ORDER BY Customer, Category, Brand, Market, (A or B)
Basically, Customer and Market in table Data links to Cust and Mkt in table Customer, and then SubMkt in table Customer links to SubMarket in table Sort. Then SortBy in table Sort would be the column I need to sort by in table Data. Hope that makes sense.
So, in the above example, all of the rows in Data containing both "Bill" for Customer and "1" for Market would be sorted by column A.
I started to write an array of objects in PHP and then I would sort the array based on an object property but this would actually require a huge overhaul on my existing code. I assume what I'm looking for can be done with a fairly straight forward query in MySQL but I don't know MySQL well enough to write that query. Any help would be appreciated!
Edit: I should have mentioned, these are just partial tables. The actual tables I'm working with are thousands of rows and every "SubMarket" does have a matching "SortBy".
Edit 2: Clarified that Customer and Market is needed in table Data to link to Cust and Mkt in table Customer.
this is just an answer showing how to do the joins.. Ignacio should have the accepted answer as he provided the hard part first :)
SELECT d.*
FROM data d
JOIN customers c on c.cust = d.customer AND c.mkt = d.market
JOIN sort s on s.submarket = c.submkt
ORDER BY
d.Customer,
d.Category,
d.Brand,
d.Market,
CASE s.sortby
WHEN 'A' THEN d.A
WHEN 'B' THEN d.B
ELSE 9999999
END
You need a CASE expression.
CASE `Sort`.`SortBy`
WHEN "A" THEN `Data`.`A`
WHEN "B" THEN `Data`.`B`
ELSE NULL
END CASE
The ELSE NULL part is optional, but it can help reveal data problems.
I have 2 tables in my database. One named data, another named changes.
The table's columns are
Data
------------
|id | name |
|-----------
|1 | Test |
|2 | Hello|
------------
changes
------------------------------------
|id | name | related_id | Comments |
|-----------------------------------
|1 | Test | 1 | Example |
|2 | Hello| 2 | Example2 |
|3 | Hello| 2 | Example3 |
------------------------------------
As you can see, changes.related_id is a foreign key to data.id.
changes can have multiple rows of same name and related_id and different comments.
After running this query, I realized that multiple rows are returned where for example, Hello can appear 2 times.
SELECT DISTINCT data.name, changes.comments FROM data LEFT JOIN changes ON data.id = changes.related_id
Result
--------------------
|name | comments |
|-------------------
|Hello | Example2 |
|Hello | Example3 |
--------------------
How do I go about making sure that only 1 row is returned? I went about SO to look for answers and many stated using DISTINCT, yet it's not working in my case.
Thanks in advance.
If you want only one record for every name in your data table and it can be any record, then you can group by the unique column (name) and use an aggregate function on the other column like max()
SELECT data.name, max(changes.comments)
FROM data
LEFT JOIN changes ON data.id = changes.related_id
GROUP BY data.name