mysql Using INNER JOIN to select multiple tables? - mysql

I want to select all fields of several table and fetch result separate but mysql return all rows together:
SELECT prod_product.*
,pub_comment.*
FROM prod_product
INNER JOIN pub_comment ON (prod_product.id = pub_comment.itemId)
WHERE prod_product.id=7744
Is there any way that i could fetch each table rows separately?
I try #prod:=prod_product.*, #comment:=pub_comment.* but mysql didn't allow me to store more than 1 row.

Execute two queries:
select * from prod_product WHERE prod_product.id=7744
and
select * from pub_comment WHERE pub_comment.itemId=7744
A single query always return single rows containing two table fields.
Anyway: what is the problem of having columns together in a single row? If you have problems with their names you can use aliases.

SELECT #prod:= CONCAT_WS(',',prod_product.field1,prod_product.field2,...)
,#comment:= CONCAT_WS(' ',pub_comment.field1,pub_comment.field2,....)
FROM prod_product
INNER JOIN pub_comment ON (prod_product.id = pub_comment.itemId)
WHERE prod_product.id = 7744
Note that CONCAT_WS will separate your fields and CONCAT will just smash then together.

Related

Trouble with LIKE CONCAT in mysql query

I have two tables: users and tabletop_questions. The users table has a column called institution_primary_function and tabletop_questions has a column called target_institutions. An example value for users.institution_primary_function = C and an example value for tabletop_questions.target_institutions = A,B,C,D,E,F.
I am trying to return only those rows where the value for users.institution_primary_function is contained in tabletop_questions.target_institutions (comma delimited list) using the below query.
SELECT * FROM tabletop_questions
LEFT JOIN users
ON users.institution_primary_function
LIKE CONCAT( '%,', tabletop_questions.target_institutions, ',%' )
However, with this query, every row from the tabletop_questions table is returned with all the values from the joined users table as NULL. Could you please advise me as to where I am going wrong?
You should normalize your data because searching through a comma-delimited string is not efficient. Yet, MySQL includes a function for this called FIND_IN_SET(). Use an INNER JOIN instead of a LEFT OUTER JOIN to only return matching records.
SELECT * FROM tabletop_questions
INNER JOIN users
ON FIND_IN_SET(users.institution_primary_function,
tabletop_questions.target_institutions)

Mysql GROUP_CONCAT using a GROUP_CONCAT in the query's IN()

I have a query:
SELECT GROUP_CONCAT(stores.store_name)
FROM stores
WHERE stores.id IN
(
SELECT
GROUP_CONCAT(users_x_stores.store_id) as stores_list
FROM users_x_stores
WHERE users_x_stores.user_id = 4
);
The subquery, when run alone, returns a group_concat of 3 results - 14,4,8.
There are corresponding rows for the IDs 14,4,8 - but the overall query only returns one store name.
If I change the subquery to simply 14,4,8 the overall query works and a concatenation of 3 store names is returned.
Can anyone tell me what I am doing incorrectly here?
Thanks.
Avoiding doing an IN on a sub query, you can probably use a JOIN.
Assuming that users_x_stores.store_id contains a single store id for that user (with another row on users_x_stores for a different store for the same user):-
SELECT GROUP_CONCAT(stores.store_name)
FROM stores
INNER JOIN users_x_stores
ON stores.id = users_x_stores.store_id
WHERE users_x_stores.user_id = 4
If sers_x_stores.store_id is a comma separated list of stores (not a good table design, and probably not what you have done, but not clear from your original post) then you could do this
SELECT GROUP_CONCAT(stores.store_name)
FROM stores
INNER JOIN users_x_stores
ON FIND_IN_SET(stores.id, users_x_stores.store_id)
WHERE users_x_stores.user_id = 4
Try this
SELECT GROUP_CONCAT(stores.store_name)
FROM stores
WHERE stores.id IN
(
SELECT
users_x_stores.store_id as stores_list
FROM users_x_stores
WHERE users_x_stores.user_id = 4
);

mysql getting difference of 2 result sets

So I have two tables. One is called superIDs which has columns "superID BIGINT" and I have another one called mainIDs which has a column called "subid BIGINT". I know that mainIDS is a subset of superIDs. How can I see the rows that are ONLY in superID but not in mainIDs.
here is my attempt at a solution:
SELECT * FROM atlas_comparables.superIDs WHERE NOT EXISTS
(SELECT * FROM atlas_comparables.mainIDs);
However, this is returning me an empty set. Any help?
Try this
SELECT * FROM atlas_comparables.superIDs WHERE the_id_column NOT IN
(SELECT the_idcolumn_ofcomparable FROM tlas_comparables.mainIDs);
Note: the_id_column is in superIDs table
the_idcolumn_ofcomparable is in MainIdstable
If the ids only appear (at most) once in each table, then you can do this relatively easily with a left outer join:
select si.*
from atlas_comparables.superIDs si left join
atlas_comparables.mainIDs mi
on si.SuperID = mi.SubID
where mi.SubId is NULL;
If you are trying to compare all the columns (as except does in other databases), then you need a more complicated query, where you include all the columns on the on clause.

Select specific fields from two inner joins

Given tables Contracts, Contract_Plans and Contract_Plan_Tags, can I select specific fields from all three within an inner join query?
Currently, I have
SELECT * FROM Contracts
INNER JOIN Contract_Plans
ON Contracts.ContractNum = Contract_Plans.ContractNum
INNER JOIN Contract_Plan_Tags
ON Contracts.ContractNum = Contract_Plan_Tags.ContractNum
WHERE Contract_Plan_Tags.tag_id = 44 OR Contract_Plan_Tags.tag_id = 45
This query returns all the fields, but is there any way to select the specific fields from the join tables?
I know I can do
SELECT ContractNum, ContractName FROM Contracts
...
...
but that only selects fields from Contracts, not the other tables.
You should learn about table aliases. The best table aliases are short abbreviations of the tables. You can then list the fields with the aliases:
SELECT c.ContractNum, c.ContractName, cpt.tag_id, . . .
FROM Contracts c
INNER JOIN Contract_Plans cp
ON c.ContractNum = cp.ContractNum
INNER JOIN Contract_Plan_Tags cpt
ON c.ContractNum = cpt.ContractNum
WHERE cpt.tag_id in (44, 45)
I notice that you use table names in the where clause, so I hope I understand the question correctly. You can use aliases (or table names) in the select and where (and group by and having) clauses.
You must prefix the fields by their table name if order for MySQL to distinguish them:
SELECT Contracts.This, Contract_Plan_Tags.That, Contract_Plans.There FROM Contracts
INNER JOIN Contract_Plans
ON Contracts.ContractNum = Contract_Plans.ContractNum
INNER JOIN Contract_Plan_Tags
ON Contracts.ContractNum = Contract_Plan_Tags.ContractNum
WHERE Contract_Plan_Tags.tag_id = 44 OR Contract_Plan_Tags.tag_id = 45
Yes, you can select any field from any table from the FROM clause. If two fields of two tables have the same name, then you must prefix the field with the name of the table (or else you get an error from the parser: "field name is ambiguous").
You may prefix the unambiguous field names too if you find it more readable.
In fact it works exactly the same way as in the WHERE clause.
Incidentally, the same requirement exists if you join tables from several databases. If two tables have the same name, you must prefix their name with the database name, but do not need to if the name is unambiguous.
Oh and you can also do this: SELECT table1.*, table2.some_field, table3.* FROM...

MYSQL SELECT: check if rowdata exists

In my SQL query i'm checking on different parameters. Nothing strange happens when there is data in each of the tables for the inserted tripcode. But when one table has no data in it I don't get any data at all. Even if the other tables have data. So I need to be able to check if the table has data in it and if it has, I need to select.
SELECT roadtrip_tblgeneral.*,
GROUP_CONCAT(distinct roadtrip_tblhotels.hotel) as hotels,
GROUP_CONCAT(distinct roadtrip_tbllocations.location) as locations,
GROUP_CONCAT(distinct roadtrip_tbltransports.transport) as transports
FROM roadtrip_tblgeneral
INNER JOIN roadtrip_tblhotels
ON roadtrip_tblgeneral.id = roadtrip_tblhotels.tripid
INNER JOIN roadtrip_tbllocations
ON roadtrip_tblgeneral.id = roadtrip_tbllocations.tripid
INNER JOIN roadtrip_tbltransports
ON roadtrip_tblgeneral.id = roadtrip_tbltransports.tripid
WHERE roadtrip_tblgeneral.tripcode = :tripcode
GROUP BY roadtrip_tblgeneral.id
Only the tables with the GROUP_CONCAT in front need the check. I already tried with the keyword EXISTS in front of it.
Thanks in advance.
The INNER JOIN keyword returns rows when there is at least one match in both tables. You can't have a match if there is no data, perhaps you want to use a LEFT JOIN or a FULL JOIN.
Left join will be use as it returns all the data from the table at left, even if there is no matching rows in right table