Select entries from table B with multiple conditions from table A - mysql

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

Related

Mysql update row value in table based on different row

I have the following table structure
TABLE A
Productid price groupId
1 100 A
2 99 A
3 0 A
4 50 B
5 49 B
6 0 B
I populate table A with prices from table B joining on Id. Sometimes table B doesn't have prices.
In cases were b doesn't have price I want to update the price to be another price from that same group, as I can't have a price of zero.
Is there an way to update table a price column using itself based on group? e.g. update productId 3 price to be the price of another product in it's group (1 or 2)
TABLE A after update
Productid price groupId
1 100 A
2 99 A
3 100 A
4 50 B
5 49 B
6 49 B
It seems silly but these are the business rules (it makes sense irl I simplified the problem for the example)
When I tried the following I got Error:
update 'Table A' t1
join (select price ,groupId from 'table A' where Price > 0 group by
groupId) as t2
on t1.groupId = t2.GroupId
SET t1.Price = t2.Price
(conn=58292) Can't reopen table: 'Table A'
I've thought of creating a third temporary table but that seems.... wrong? I am sure there must be a way to do this using update statement and joins
I would phrase the query as:
update tablea a
inner join (select groupId, max(price) price from tablea group by groupId) a1
on a1.groupId = a.groupId
set a.price = a1.price
where a.price = 0 and a1.price > 0
Notes:
the table name should be surrounded with single quotes (those stand for literal strings) - if your table name really contains spaces, then use backticks for quoting (or better, yet, fix the table name!)
I changed the subquery to make it a valid aggregation query - yours has non-aggregated columns that do not belong to the group by clause, which is not a good practice, and might generate errors, depending on the SQL mode of your database
In this demo on DB Fiddlde with your sample data, the content of the table after update is:
Productid | price | groupId
--------: | ----: | :------
1 | 100 | A
2 | 99 | A
3 | 100 | A
4 | 50 | B
5 | 49 | B
6 | 50 | B

Select data from multiple tables in mysql database

I have a database with multiple tables that I am selecting from. In some tables I have 2 entries fr the same case and while selecting I want to retrieve both those values. My issue is if out of 8 tables 2 tables have two entries for a column then in the final output i see 4 rows for the same case with columns populated from all the tables which makes it difficult to know which columns have two entries.
Example
Table1:
case_id company_id date location_type
1 123 08-07-2020 rest1
2 234 01-01-1999 rest2
3 456 01-01-1995 rest1
Table2:
Case_id type Series
1 A ABCD
1 A GEFT
2 B TRFG
3 A HJKL
Table3:
Case_id type Series
1 A UIPO
2 A GGTH
3 B TYUI
The query:
SELECT Table1.company_id,"|",Table2.type, Table3.type FROM Table1
LEFT JOIN Table2 ON Table1.case_id = Table2.case_id
LEFT JOIN Table3 ON Table1.case_id = Table3.case_id
where Table1.location_type = "rest1"
This is what I get:
company_id type type
123 A A
123 A A
456 A B
How do I get:
company_id type type
123 A A
123 A NULL
456 A B

Get records from table 1 and join it from another table when the table 2 value does not exist

1st Table - explore_offers:
- id
- Primary Key - offer_unique
2nd Table - participated_explore_offers:
- id
- email - user_email
- Primary Key - offer_unique
What i want:
* Show 1st Table records, and exclude those records, which are in the 2nd table with a specific email found
ex:
SELECT eo.*
, peo.user_email
FROM explore_offers eo
LEFT
JOIN participated_explore_offers peo
ON eo.offer_unique = peo.offer_unique
WHERE peo.user_email = 'test#gmail.com'
I've tried that example, and i'm getting 0 records.
I have 2 records in the first table, and one in the second table, and the result i want is:
*. get that one record from the first table, where this record does NOT exist in the second table.
1st Table content:
Nr id Primary Key
1 0 m1
2 1 m2
2nd Table Content
Nr id user_email Primary Key
1 0 test#gmail.com m1
1 0 test2#gmail.com m2
Expected
Nr id Primary Key
1 1 m2
What i had:
0 Records
SQL DEMO
Try this :
select * from explore_offers
where offer_unique not in
(select offer_unique from participated_explore_offers where user_email='test#gmail.com')
Move the email filteration to the JOIN condition to make it work with LEFT JOIN:
SELECT eo.*,peo.user_email
FROM explore_offers eo
LEFT JOIN participated_explore_offers peo ON (eo.offer_unique = peo.offer_unique)
AND peo.user_email = 'test#gmail.com'
WHERE peo.user_email is null;
demo:
| Nr | id | offer_unique | user_email |
|----|----|--------------|------------|
| 2 | 1 | m2 | (null) |

Update all rows associated to duplicates of another table

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.

Select row belonging to multiple categories

I've got 2 tables. The first table is full of entries. The second table defines what categories that entry belongs to:
Table 1:
entry_id | title
1 | Entry1
2 | Entry2
3 | Entry3
Table 2
entry_id | cat_id
1 | 233
1 | 234
1 | 678
2 | 235
2 | 453
2 | 21
3 | 234
3 | 233
I'm trying to select an entry with a single query of all posts belonging to multiple categories. For example, I want to return the entries belonging to category ids, 233 and 234. I believe this needs a subquery although I'm not quite sure. Any help anybody? :)
Learn about SQL joins.
SELECT * FROM tbl1 JOIN tbl2 USING (entry_id) WHERE cat_id IN (233,234);
See it on sqlfiddle.
UPDATE
To select all entries in both categories, you could group the results of the join and only select those groups that have contain both categories:
SELECT tbl1.*
FROM tbl1 JOIN tbl2 USING (entry_id)
WHERE cat_id IN (233,234)
GROUP BY entry_id
HAVING COUNT(DISTINCT cat_id) = 2
See it on sqlfiddle.
The COUNT(DISTINCT cat_id) can obviously be replaced with the (much less expensive) COUNT(*) if (entry_id, cat_id) is known to be unique in tbl2.
Try this:
select * from entity e
where exists (select * from category c where c.entry_id=e.entry_id AND c.cat_id=233)
and exists (select * from category c where c.entry_id=e.entry_id AND c.cat_id=234)
This returns rows that belong to both 233 and 234 (this is how I read your question, anyway; I may have misunderstood the "belonging to multiple categories" part).