The query is supposed to do the following:
Obtain the question and associated answers based on the identification number of the question. (In this case the identification number is called account_id. Order them so that each question (and it's appropriate answers) are lined up in order.
The query:
SELECT *
FROM quiz_questions q
JOIN quiz_answers a
ON q.account_id = a.account_id
WHERE q.account_id = 1840979156127491
ORDER BY q.question_id
ASC LIMIT 5
The quiz_questions table and contents:
The quiz_answers table and contents:
Strange altered results:
As you can see where the question_id is ordered, all of the values are 1 however, the other question_id field (These fields match if you look at the previous data) are representing two, like they should. Also, even though the question (with the id of 2) is displayed in the secondary question_id field, the text for the question still belongs to question 1: (do you like waffles) apposed to (do you like pancakes).
What is causing these results? Here's what the expected results should look like: (Ignoring duplicate fields).
+------------------+-------------+----------------------+-----------+----------------------+---------+
| account_id | question_id | question | answer_id | answer | correct |
+------------------+-------------+----------------------+-----------+----------------------+---------+
| 1840979156127491 | 1 | Do you like waffles | 1 | Yes i like waffles | 1 |
| 1840979156127491 | 1 | Do you like waffles | 5 | I kinda like waffles | 1 |
| 1840979156127491 | 1 | Do you like waffles | 6 | Not at all | 0 |
| 1840979156127491 | 2 | Do you like pancakes | 7 | Yes | 1 |
| 1840979156127491 | 2 | Do you like pancakes | 8 | No | 0 |
+------------------+-------------+----------------------+-----------+----------------------+---------+
You need to join by account_id and also question_id
SELECT * FROM `quiz_questions`
INNER JOIN `quiz_answers`
ON `quiz_questions`.`account_id` = `quiz_answers`.`account_id`
AND `quiz_questions`.`question_id` = `quiz_answers`.`question_id`
WHERE `quiz_questions`.`account_id` = '1840979156127491'
ORDER BY `quiz_questions`.`question_id`
ASC LIMIT 5
Related
This question already has answers here:
How to join two tables using a comma-separated-list in the join field
(5 answers)
Closed 2 years ago.
I have two tables, First one is products where it has list of products with some specifications, in the other hand I have a table with clients and what type of product they want, they might want a product in any town of a list exactly as explained in the following tables,
Products Table like
| id | owner | userid | city | town | status | price |
| 1 | jon spee | 10 | 10 | 4 | 0 | 10500 |
| 2 | Hiss Roe | 10 | 7 | 9 | 0 | 20000 |
| 3 | John Smi | 10 | 10 | 12 | 0 | 10000 |
Clients Table like
| id | fullname | userid | city | towns | status | price |
| 1 | name 1 | 10 | 10 |4,8,6,2| 0 | 20000 |
| 2 | name 2 | 10 | 7 | 7,2,9 | 0 | 25000 |
| 3 | name 3 | 10 | 10 | 1 | 0 | 20000 |
MySQL Query :
SELECT *
FROM clients
INNER JOIN products
ON (
clients.userid = products.userid AND
clients.price >= products.price AND
clients.city = products.city AND
clients.status = products.status
I want it to check also in towns like for each town it executs this query (dynamically),
(products.town LIKE '%4%' OR products.town LIKE '%8%' OR products.town LIKE '%6%' OR products.town LIKE '%2%')
You could go with this query
SELECT *
FROM clients
INNER JOIN products
ON (
clients.userid = products.userid AND
clients.price >= products.price AND
clients.city = products.city AND
find_in_set(clients.town, products.town) AND
clients.status = products.status
you can also fetch it in php and create your statement based on the results fetched
Your primary effort should go into fixing your data model. Don't store multiple integer values in a string column. You should have a separate table to store the relation betwen clients and towns, which each tuple on a separate row.
That said: for your current design, you can join on find_in_set():
on
clients.userid = products.userid
and ...
and find_in_set(product.town, client.towns)
I have a table with multiple rows for each customer and and a visit_date. The visit date can be null as well.
My tables are as below:
customers:
id | name | email
1 | John Doe1 | a.b#gmail.com
2 | John Doe2 | b.c#gmail.com
3 | John Doe3 | x.y#gmail.com
store_customers
id | customer_id | store_id | email_optedin | visit_date
1 | 1 | 1 | 1 | 2015-11-30
2 | 1 | 2 | 1 | 2016-05-08
3 | 1 | 3 | 1 | null
4 | 2 | 1 | 1 | 2015-04-30
5 | 2 | 2 | 1 | 2015-08-40
6 | 2 | 3 | 1 | 2015-12-12
7 | 3 | 1 | 1 | null
8 | 3 | 2 | 1 | null
9 | 3 | 3 | 1 | null
I am trying to retrieve customers who either have not had a visit to the any of the three stores or have not visited since a specified date (e.g. 2016-04-15).
I am expecting customers 2 and 3 but not 1.
I tried this query:
select distinct * from customers
inner join store_customers on store_customers.customer_id = customers.id
where customers.email != '' and
store_customer.store_id in (1,2,3) and customers.emailStatus not in ('Unverified','Bounced','Spammed')
and
(
store_customer.email_optedin = 1
and max(store_customers.visit_date) <= '2016-04-15'
or account_customer.visit_date is null
);
This does not work. I somehow need to, for the set of store ids), I need to select customers who have either not had any visit (all nulls for visit date for the specified stores) or the if one or more visit dates are available then compare the max date to the specified date.
I found similar questions but none of the answers has worked for me, mainly because of the requirement of selecting either those customers who have no visit or if they do atleast one, then to compare the latest visit date from the set of stores in the joined table.
I am trying to do this all in one query but if that is not possible then I can break it up as well. I also do not want to change the order of joins because there are many other things added on to this query and changing the order of joins may become a problem.
I really appreciate any help that can be provided.
Regards,
Waqar
Try this query
SELECT
customers.id,
customers.name,
MAX(store_customers.visit_date)
FROM
customers LEFT JOIN store_customers on customers.id = store_customers.customer_id
GROUP BY customers.id,customers.name
HAVING MAX(store_customers.visit_date) < '2016-04-15' OR MAX(store_customers.visit_date) IS NULL
I have three tables group_sentences, group_sentences_attributes and group_senteces_categories.
I have an attributes array which I am using in query with IN (after implode).
Then I have one category ID because they are stored recursively, so no need for an array.
I need to select one group number where is the biggest match for $attributesArray and of course category too.
Here is table group_sentences_attributes
+-----+-------+-----------+
| id | group | attribute |
+-----+-------+-----------+
| 1 | 1 | 3564 |
| 2 | 1 | 3687 |
| 3 | 1 | 3689 |
| 4 | 2 | 3687 |
| 5 | 2 | 3564 |
+-----+-------+-----------+
Here is group_sentences_category
+-----+-------+----------+
| id | group | category |
+-----+-------+----------+
| 1 | 1 | 1564 |
| 2 | 1 | 1221 |
| 3 | 1 | 1756 |
| 4 | 2 | 1358 |
| 5 | 2 | 1125 |
+-----+-------+----------+
Here is my query, but I am afraid that it won't do the job done.
SELECT group_categories.group
FROM group_categories, group_attributes
WHERE group_categories.category = '$category'
AND group_attributes.attribute IN ($attributesArray)
GROUP BY group_categories.group
ORDER BY count(group_attributes.attribute)
Any help would be appreciated, thanks.
First, the table in your query do not match the tables in the question. I am guessing they are simply missing the "sentence". Then, you have no join clause. Simple rule: Never use commas in the from clause.
group is a lousy name for a column, because it is a keyword in SQL. The following may be what you are looking for:
SELECT gc.groupid
FROM group_sentences_attributes sa JOIN
group_sentences_category sc
ON sa.groupid = sc.groupid
WHERE sc.category = '$category' AND
sa.attribute IN ($attributesArray)
GROUP BY sa.groupid
ORDER BY count(sa.attribute);
If you only want one row, then add LIMIT 1 to the end.
I got the following MySQL table:
+----+--------+------+
| id | answer | type |
+----+--------+------+
>| 1 | -1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 1 |
>| 4 | -1 | 2 |
| 5 | 4 | 2 |
| 6 | 4 | 1 |
>| 7 | -1 | 1 |
| 8 | 7 | 2 |
>| 9 | -1 | 2 |
>| 10 | -1 | 1 |
>| 11 | -1 | 2 |
+----+--------+------+
> = original comment
The entries with answer = -1 are the original comments.
The entries with answer != -1 are answers to the comment with the respective id.
Furthermore there are types of comments (in this case 1 or 2).
Now I want to retrieve the original comments (for a specified type and a specified limit) and their answers (type and limit do not matter). Further it would be great to group the result by the two types (again, only the original comment's type matters for grouping).
A query result for type=1 and limit=2 should look like that (not grouped yet):
+----+--------+------+
| id | answer | type |
+----+--------+------+
>| 1 | -1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 1 |
>| 7 | -1 | 1 |
| 8 | 7 | 2 |
+----+--------+------+
I have tried several kinds of queries for hours now, can I implement it without a procedure? What would the procedure look like?
I would appreciate your help a lot.
Use a subquery to get 2 original comments of type-1 first, then join the table again to get both original comments and responses.
select b.*
from (
select id
from answers
where type = 1 and answer = -1
limit 2) a
join answers b on a.id = b.id or a.id = b.answer;
fiddle
To select 2 original comments of each type, you'll need to use user-defined-variable to index each original comment. The following code indexes the first original comment as 1, the second one as 2, and so on, then resets to 1 when the type changes. Finally in the final where statement filter out indices greater than 2.
select b.*, a.idx
from (
select id, #idx:=if(#type=a.type,#idx+1,1) idx, #type:=a.type
from (select id, type from answers2 where answer is null order by type) a
join (select #type:=null, #idx:=null) b) a
join answers2 b on a.id = b.id or a.id = b.answer
where a.idx <= 2;
fiddle
Store it as a separate column or even a different table if you are worried about too much data duplication. You are overthinking it.
I here today with a question that has left me rather confused and puzzled. Perhaps someone out there could give me a bit of assistance.
I have three table as followed. Please note that they are simplified for this question.
//table_checks//
check_id |task_id| status
1 | 1 | Done
2 | 1 | Done
3 | 1 | Done
4 | 2 | Done
5 | 2 | Not Done
6 | 2 | Not Done
7 | 2 | Not Done
8 | 2 | Done
9 | 3 | Done
10 | 3 | Done
11 | 3 | Not Done
12 | 3 | Done
//table_user//
user_id | email | type
1 | a#a.com | IN
2 | b#b.com | IN
3 | c#c.com | EX
//table_chk_usr//
check_id |user_id
1 | 1
2 | 1
3 | 1
4 | 2
5 | 2
6 | 2
7 | 2
8 | 2
9 | 3
10 | 3
11 | 3
12 | 3
Here are three tables with its relation in the table_chk_usr table.
My question is how do I query and select rows of table_user with type 'IN' from table table_user where all of users assigned task_ids in the table_checks are with the status = done.
So the expected result should be as follows
//table_user//
user_id | email | type
1 | a#a.com | IN
Since user_id with 1 has completed all task_ids with status done.
I hope this makes sense to those of you who are reading. Any help will be much appreciated.
Please Note that I am using PHP as my server side language, if that helps in any way.
I think this is what you are looking for.
select user.user_id, user.email, user.type,
sum(if(status = 'done',1, 0)) as done, count(*) as checks
from checks
join chk_user on checks.check_id = chk_user.check_id
join user on chk_user.user_id = user.user_id
group by chk_user.user_id
having done = checks
sqlFiddle
You could use a join here, but there may be a better way to do it.
SELECT * FROM table_checks
INNER JOIN table_chk_usr
ON table_checks.check_id = table_chk_usr.check_id
INNER JOIN table_user
ON table_chk_usr.user_id = table_user.user_id
WHERE table_checks.status = 'Done'
AND table_user.type = 'IN'