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

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
);

Related

SELECT DISTINCT ON Simple Table Unique Values

I have two tables, one with unique LTV (lifetime values) with around 3300 records and then the transaction log with more than 5000 transactions.
Whenever I run the following query it keeps showing me duplicate values. I just want to look up the person's first name and last name from the first column.
SELECT
SociAll.firstname,
SociAll.lastname,
SociLTV.Email,
SociLTV.LTV
FROM
SociAll
INNER JOIN SociLTV ON SociAll.Email = SociLTV.Email
Sometimes the same email address is repeated 3 or 4 times depending on the number of transactions from that given user, even though the LTV is the exact same value.
How can I have only 1 record per email address on this Query?
Try this:
SELECT
SociAll.firstname,
SociAll.lastname,
SociLTV.Email,
Sum(SociLTV.LTV)
FROM
SociAll
INNER JOIN SociLTV ON SociAll.Email = SociLTV.Email
GROUP BY SociAll.firstName,SociAll.LastName,SociAll.Email
You can also use COUNT() or MIN(), or MAX() etc. on the last column. If you don't care at all about the last column, remove it.
You can also do the following if you don't care at all about the SocilTV records
SELECT DISTINCT
SociAll.firstname,
SociAll.lastname,
SociLTV.Email,
FROM
SociAll
INNER JOIN SociLTV ON SociAll.Email = SociLTV.Email
We don't need a sum of the LTV since the LTV already has the final value. To answer the question I had a list of lifetime values of each customer.
SELECT
SociAll.firstname,
SociAll.lastname,
SociLTV.Email,
SociLTV.LTV
FROM
SociAll
INNER JOIN SociLTV ON SociAll.Email = SociLTV.Email
GROUP BY SociAll.firstName,SociAll.LastName,SociAll.Email
If I wasn't comparing the two tables and simply had a list of transactions, this query works great. It's a derivative of your solution.
SELECT
SociAll.Email,
SociAll.firstname,
SociAll.lastname,
Sum(SociAll.Price) as LTV
FROM
SociAll
GROUP BY SociAll.firstName,SociAll.LastName,SociAll.Email
As I posed the question I was using a pre-established 'LTV' table export from a list of customers and their lifetime value from an excel spreadsheet.
Thank you so much for your contributions. I hope others find this post useful.

WHERE clause with INNER JOIN and Sub Query

I have achieved my desired query but I want to know how this one worked. I have multiple tables on my database and my requirements was to take the id from table called product and using this id, I want to retrieve some data from multiple tables and product id is a foreign key to the other tables. The query below works fine (by the way I was just experimenting and luckily got this query).
SELECT ponsfdp.*, product.pName, product.pImage, product.productSizes FROM product
INNER JOIN priceOnSizesForDigitalPrinting AS ponsfdp ON ponsfdp.pId_fk =
(SELECT pId FROM product WHERE pName LIKE "%booklet%")
WHERE pName LIKE "%booklet%";
But when I tried this query,
SELECT ponsfdp.*, product.pName, product.pImage, product.productSizes FROM product
INNER JOIN priceOnSizesForDigitalPrinting AS ponsfdp ON ponsfdp.pId_fk =
(SELECT pId FROM product WHERE pName LIKE "%booklet%");
It contains all the data even with null fields too. Can someone explain to me how it works? My personal opinion is both query should return same data because on the second query, I am using a subquery and it returns only one id, on the other hand, first query has a WHERE clause which generates the same id but by the help of name. How does the first query returns very specific columns and second return all columns even null columns too? I need an explanation for both queries.
Your first query also returning all rows as returned from your second query. But, when you are adding the last filter-
WHERE pName LIKE "%booklet%"
It's just keeping one single row from all rows where pName is like 'booklet'. You can consider the output from your second query as a single table and your logic working as below-
SELECT * FROM (
SELECT ponsfdp.*, product.pName, product.pImage, product.productSizes
FROM product
INNER JOIN priceOnSizesForDigitalPrinting AS ponsfdp
ON ponsfdp.pId_fk = (SELECT pId FROM product WHERE pName LIKE "%booklet%")
)A
WHERE pName LIKE "%booklet%"
Hope this will at least give you some insight of your query.
I don't see any need for a subquery here. You should be using the where condition to select rows from your FROM table, then use the ON clause of your join to find the right record(s) in your joined table for each row of the FROM table:
SELECT ponsfdp.*, product.pName, product.pImage, product.productSizes
FROM product
INNER JOIN priceOnSizesForDigitalPrinting AS ponsfdp
ON ponsfdp.pId_fk = pId
WHERE pName LIKE "%booklet%";

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)

Use count of unrelated table in SQL query

I have this query:
select skill.name, IFNULL(Round(((SUM(ROUND((student_skills.value/skill.value)*100,0)))/82),0),0) as successRate from skill left JOIN student_skills on skill.id = student_skills.skill_id group by skill.name
This query returns exactly what I want but I need to replace constant 82 (just for example) with number of rows in table user (something like COUNT(user.name)).
Problem is that user is not related to skill or student_skill table in any way.
How should I alter my query so that it would use current count of users?
Thanks
Use a subquery
select skill.name,
IFNULL(Round(((SUM(ROUND((student_skills.value/skill.value)*100,0)))/(select COUNT(*) from user)),0),0) as successRate
from skill
left JOIN student_skills on skill.id = student_skills.skill_id
group by skill.name

mysql Using INNER JOIN to select multiple tables?

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.