I found the solution for add query column by case when then from same table depending on column value but It can't solve my problem.
I have two tables.
Table: pools
id date title description
------ ---------- -------------- ---------------------
1 2016-11-10 This is pool 1 this is description
Table: votes
id date time pool_id option_id uid
------ ---------- -------- ------- --------- ------------------------------
1 2016-11-10 21:22:23 1 1 XodxfBfeRdZsOFRNbJ0AecMgpyo2
2 2016-11-10 21:22:23 1 2 PhbZ675XdZeL59QFKLQq8u1uQyg2
I want to query output by passing uid in query.
id date title voted
------ ---------- -------------- ---------------------
1 2016-11-10 This is pool 1 YES
You can LEFT JOIN 2 tables pools and votes. Then check if corresponding entry exists in votes, show YES else NO.
For better explanation, I created 1 more entry in pool table.
INSERT INTO pools VALUES (2, '2016-11-11', 'This is pool 2', 'this is description');
Below Query will give you desired output:
SELECT p.id, p.date, p.title, IF(v.id IS NOT NULL, 'YES', 'NO') AS voted
FROM pools p LEFT JOIN votes v
ON p.id = v.pool_id
AND v.uid = 'XodxfBfeRdZsOFRNbJ0AecMgpyo2';
Query Explanation
LEFT JOIN will return row from LHS table and NULL from RHS table if corresponding value is not present.
We can then add a check in SELECT statement to create custom column voted.
OUTPUT
id date title voted
-------------------------------------
1 2016-11-10 This is pool 1 YES
2 2016-11-11 This is pool 2 NO
Related
Consider the table Audit, and AuditStatus.
Where auditId in AuditStatus is a foreign key, mapping the pk of table Audit.
table Audit
id | auditName |
1 | test |
2 | fooTest |
3 | barTest |
table AuditStatus
id | auditId | status |
11 | 1 | started |
12 | 1 | completed |
13 | 2 | started |
How can I only select the entries of table Audit, which do not have a AuditStatus.status 'completed'.
The result in this case would be:
2 | fooTest |
3 | barTest |
I have updated the question and the result example, to make it more clear. The relation Audit -> AuditStatus is a one to many. And I want to exclude the Audits which have a refrerence to an AuditStatus with status 'complete'
You should post your attempted query into your question, not as comment. Anyway, your query is actually correct but your condition is incorrect. Let's inspect your query:
SELECT *
FROM Audit a
WHERE NOT EXISTS (
SELECT s.auditId
FROM AuditStatus s
WHERE a.id = s.auditId AND s.status != 'completed'
);
You're suppose to find where the status is not complete, which is true in the subquery but the problem here is you're doing a NOT EXISTS which negates the correct result you're getting from the subquery.
This is what your subquery will return:
id
auditId
status
11
1
started
13
2
started
Then when your NOT EXIST negates the auditId being returned, you'll get this result instead:
id
auditName
3
barTest
Which is correct according to the condition; auditId=3 wasn't returned in the subquery. What you need to modify is actually very simple, you just need to make the subquery return status = completed as true then NOT EXISTS will return any Audit.Id that doesn't match with the correlated subquery. Therefore:
SELECT *
FROM Audit a
WHERE NOT EXISTS (
SELECT s.auditId
FROM AuditStatus s
WHERE a.id = s.auditId AND s.status = 'completed'
);
And that's it, you should be getting the result you looking for.
Demo fiddle
maybe use a left join like below which only joins on Audit Status on Fk as well as status constraint
SELECT *
FROM Audit A
LEFT JOIN AuditStatus ATS
ON A.id= ATS.auditId AND ATS.Status ='completed'
WHERE AS.auditId IS NULL
I've been trying to wrap my brain around this using joins, subquery joins, not exists clauses and I keep failing to come up with a query that produces the correct results.
Table A - PRIMARY id (irrelevant for this issue)
id | campaign_id | user_id
--------------------------
1 1 1
2 1 2
3 0 3
4 2 3
5 1 2
Table B - UNIQUE campaign_id+user_id
campaign_id | user_id | admin
-----------------------------
1 1 1
1 2 0
1 3 0
2 3 0
What I need to do is find instances of Table B where the user no longer has an entry in Table A that correspond with the campaign_id in Table B. Table A is the main content and they can have multiple entries of Table A that are present in the campaign. Table B is a member table that indicates they're a member of the campaign and whether they're an admin or not. In addition, they could have in entry in Table B as admin, but not have an entry in Table A, so the query must check for admin=0.
In the example entries, the invalid entry in Table B would be campaign_id 1, user_id 3
Use an outer join and then state in the where clause that the outer joined table's user_id is null:
select tblB.*
from tblB
left join tblA
on tblA.campaign_id = tblB.campaign_id
and tblA.user_id = tblB.user_id
where tblB.admin = 0
and tblA.user_id is null
MySQL 5.6
We have two tables: cars and views.
Cars Views
---+------- ---+-------
id | desc id | car_id
---+------- ---+-------
1 | desc1 1 | 1
2 | Desc1 2 | 2
3 | desc2 3 | 3
The problem is with the desc field in the table cars. That row had to be unique but we unfortunately allowed the users to fill in uppercased values, which brought us to the situation of having (according to the example above) two duplicated rows: desc1 and Desc1.
The way to fix that is DELETE the duplicated cars, and keep only the first one. We know how to deal with that.
Our problem comes before that, when updating the related table, where some views are associated to a car which has a duplicated desc (for instance a car which is going to be removed). Those views should be updated for being assigned to the first of the duplicated cars (in this case the car id #1)
After the UPDATE, we'd like this result in views:
Views
---+-------
id | car_id
1 | 1
2 | 1
3 | 3
We are able to get all the ids of the duplicated cars and deal with the deletion but we're stuck with this UPDATE.
The solution will be to create a mapping table with before/after values for description ids.
The result should look something like:
Before | After
---------------
1 | 1
2 | 1
3 | 3
That table can be created with something like this:
SELECT
cars.id AS before_id,
fixed.lowest_id AS after_id
FROM cars
JOIN (
-- The lowest id value for each duplicate description
SELECT
MIN(id) AS lowest_id,
LOWER(desc) AS lower_desc
FROM cars
GROUP BY LOWER(desc)
) fixed
ON LOWER(cars.desc) = fixed.lower_desc
You can then have your views match to that mapping table to pull the new "correct" id value.
UPDATE Views AS v
JOIN (SELECT c1.id AS oldID, MIN(c2.id) AS newID
FROM Cars AS c1
JOIN Cars AS c2 ON LOWER(c1.desc) = LOWER(c2.desc)
HAVING oldID != newID) AS c
ON v.car_id = oldID
SET v.car_id = newID
The subquery finds the primary ID for each ID that contains a duplicate description. Joining this with the Views table provides the information needed to make the replacements.
There are a number of left join questions already, but still I can't quite put my finger on this issue. The WHERE condition doesn't look sensible to move.
The problem is that there should be 4 rows returned but only 1 is.
In checking the left join conditions, there is 1 row returned for each left join, which is correct for the number of records in the table, however the query below returns 1 record instead of 4, but I can't see how to return 4, yet.
Query follows: (Gives 1 result not 4; 4 being expected)
SELECT
list.uid,
list.business_uid,
list.creator_name,
business.company_name,
list_alias.uid AS list_alias_uid,
list_alias.alias AS list_alias,
list_member.uid AS list_member_uid,
mailbox.full_name AS list_member_name,
mailbox.email_address AS list_member_email_address
FROM
mailbox,
business,
list
LEFT JOIN
list_alias ON list_alias.list_uid=list.uid
LEFT JOIN
list_member ON list_member.list_uid=list.uid
WHERE
list.business_uid='1'
AND list.business_uid=business.uid
AND mailbox.uid=list_member.mailbox_uid
ORDER BY
list.full_name ASC
Data:
Business UID 1 has 4 lists
SELECT * FROM list WHERE business_uid=1 -- gives 4 results
SELECT * FROM list_alias WHERE list_uid IN (SELECT uid FROM list WHERE business_uid=1) -- gives 1 result
SELECT * FROM list_member WHERE list_uid IN (SELECT uid FROM list WHERE business_uid=1) -- gives 1 result
Any pointers on what I could check would be welcome.
Table Sample Data:
list:
uid | business_uid | creator_name | full_name
--------------------------------------------------
1 1 List Maker Subscribe to W
2 1 List Maker Subscribe to X
3 1 List Maker Subscribe to Y
4 1 List Maker Subscribe to Z
business:
uid | company_name
-------------------
1 List Company
list_alias:
uid | list_uid | alias
----------------------------------------
1 1 subscriber#list-url.com
list_member:
uid | list_uid | mailbox_uid
------------------------------------
1 1 1
mailbox:
uid | full_name | email_address
-------------------------------
1 I am He me#me.com
Try this using a single join methodology, like so.
SELECT list.uid,
list.business_uid,
list.creator_name,
b.company_name,
la.uid AS list_alias_uid,
la.alias AS list_alias,
lm.uid AS list_member_uid,
m.full_name AS list_member_name,
m.email_address AS list_member_email_address
FROM list LEFT JOIN list_member lm ON lm.list_uid=list.uid
LEFT JOIN mailbox m ON m.uid=lm.mailbox_uid
LEFT JOIN business b ON list.business_uid=b.uid
LEFT JOIN list_alias la ON la.list_uid=list.uid
WHERE list.business_uid=1
ORDER BY list.full_name ASC
Question: What are the values of 'uid' from the 'list' table? Because 'uid' is not the same as 'business_uid'. What I mean is ...
If the 'list' table has this ...
'uid' 'business_uid'
1 1
2 1
3 1
4 1
Then that is the problem. You are returning the same 'busines_uid' but a different 'uid' which means it will only match the first record.
Given the following tables:
Topic
id, last_updated_child_id
Response
id, topic_id, updated_at
How do I update the Topic table so the last_updated_child_id is equal to the latest response id (based on date).
So for example given:
Topic
id last_updated_child_id
-- -----------------------
1 null
2 null
3 null
Response
id topic_id updated_at
-- ---- ----
1 1 2010
2 1 2012
3 1 2011
4 2 2000
I would like to execute an UPDATE statement that would result in the Topic table being:
id last_updated_child_id
-- -----------------------
1 2
2 4
3 null
Note: I would like to avoid temp tables if possible and am happy for a MySQL specific solution.
Not very efficient, but relatively simple:
UPDATE topic
SET last_id = (SELECT id
FROM response
WHERE topic_id = topic.id
ORDER BY updated_at DESC
LIMIT 1);