Replace several entries - mysql

I have two similar tables with the same columns and same type of data. The goal is to get the data of table_a but replace all entries with table_b values if there are value with the same id.
So I have the following two selects:
SELECT table_a.id, table_a.text
and
SELECT table_b.id, table_b.text
In pseudo code:
iterate table_a data
if table_a.id == table_b.id then
table_out.id = table_b.id
table_out.text = table_b.text
else
table_out.id = table_a.id
table_out.text = table_a.text
end if
end iterate
The tables table_a and table_b data shall not be touched. Just the output of the select shall contain the data.
I was thinking first of joining the two tables with a left join. Then I would need a kind of if to switch columns for the select.
Thank you.

I would recommend coalesce() for this purpose:
select a.id,
coalesce(b.text, a.text) as text
from table_a a left join
table_b b
on a.id = b.id
order by a.id;

You can use LEFT JOIN it will give you all table_a record and common record between two tables. then use case logic to get require output
SELECT
t1.id,
(CASE WHEN t1.id=t2.id THEN t2.text ELSE t1.text END) AS text
FROM table_a t1
LEFT JOIN table_b t2
ON t1.id=t2.id
ORDER BY t1.id
DEMO

Related

SQL Inner Joins Giving Incorrect Count Values in MS ACCESS

I am trying to use join to connect multiple tables in MS Access to get count values. But I don;t know it gives wrong count values. If I try to join them individually, then it gives me correct count values.
I have 3 Tables. Table 2 and Table 3 are independent and are connected to Table 1. Test 2 and test 3 are basically text values and I want to count the rows .
Table1(ID1(Primary Key),Name)
Table2(ID2(Primary Key), ID1(Foreign Key), Test2)
Table3 (ID3(Orimary Key), ID1(Foreign Key), Test3)
The Query that I get from MS Access is given below:
SELECT Table1. ID1, Count(Table2.Test2) AS CountOfTest2, Count(Table3.Test3) AS CountOfTest3
FROM (Table1 INNER JOIN Table2 ON Table1.ID1 = Table2.ID2)
INNER JOIN Table3 ON Table1. ID1 = Table3.ID3
GROUP BY Table1.ID1;
But this gives me wrong Count Values.
Can someone please help me.
Thanks.
When I use it individually, it gives me correct count value:
SELECT Table1. ID1, Count(Table2.Test2) AS CountOfTest2
FROM Table1 INNER JOIN Table2 ON Table1.ID1 = Table2.ID1
GROUP BY Table1.ID1;
SELECT Table1. ID1, Count(Table3.Test3) AS CountOfTest3
FROM Table1 INNER JOIN Table3 ON Table1.ID1 = Table3.ID1
GROUP BY Table1.ID1;
But when I try to join Table1, Table2 and Table 3 in MS Acces, it gives me incorrect count values.
SELECT Table1. ID1, Count(Table2.Test2) AS CountOfTest2, Count(Table3.Test3) AS CountOfTest3 FROM (Table1 INNER JOIN Table2 ON Table1.ID1 = Table2.ID1) INNER JOIN Table3 ON Table1. ID1 = Table3.ID1 GROUP BY Table1.ID1
As per my understanding it is taking the count value of 1st query in the parenthesis and multiplying it with the count values of the other inner join.
I have tried many things but don't know what to do. Access adds parenthesis for some reason.
If I can assume test2 and test 3 are unique to each record (perhaps it would be better to count the PK?)
SELECT Table1.ID1
, Count(distinct Table2.Test2) AS CountOfTest2
, Count(distinct Table3.Test3) AS CountOfTest3
FROM Table1
INNER JOIN Table2
ON Table1.ID1 = Table2.ID2
INNER JOIN Table3
ON Table1.ID1 = Table3.ID3
GROUP BY Table1.ID1;
Or you may have to get the counts before the joins though the use of inline views. You could use window functions if MSSQL SERVER but Access needs the inline views.
SELECT A.ID1
, B.CountOfTest2
, C.CountOfTest3
FROM Table1 A
INNER JOIN (SELECT Table2.ID2, count(table2.test) as CountOfTest2
FROM Table2
GROUP BY Table2.id) B
ON Table1.ID1 = B.ID2
INNER JOIN (SELECT Table3.id, count(table3.test3) as CountOfTest3
FROM Table3
GROUP BY Table3.id) C
ON B.ID1 = C.ID3
GROUP BY A.ID1;
Yup i had the same problem when i was trying to do this. just use the double sql function to counteract the html and you should be good. once the query has been doubled it will react like a C++ quota statement. If this fails you can always just quantify the source fields to adhear to the table restrictions. its actually a piece of cake i hope this helped.

Join/Update between Three Tables

Currently to get data updated in Table3 that depends on conditions in Tables1 and Table2 I am doing this:
Update Table_B as T1
Inner Join Table_A as T2
On T1.S_ID=T2.ID
Set T1.Percent = T2.Percent
Update Table_C as T1
Inner Join Table_B as T2
On T1.ID=T2.J_ID
Set T1.B = T2.B
Where T2.Percent=100
I would like to not store or update TableB with TableA Percent and somehow do the join in a single statement.
update table_b T1 set T1.Percent=(select T2.Percent from table_a T2 where T1.S_ID=T2.ID)
update table_c T1 set T1.B=(select T2.B from table_b T2 where T1.ID=T2.J_ID) where exists(select * from table_b T3 where T1.ID=T3.J_ID and T3.percent=100)
This isn't valid syntax in an UPDATE statement
Set T1.Percent as T1.Percent
^^
And this isn't valid
Set T1.B as T2.B
^^
The syntax in the UPDATE statements in the question do not look valid.
The SET assignment operator is an equals sign, not an As keyword.
And T1.Percent = T1.Percent doesn't make much sense, since there doesn't seem to be any point to setting a column to its current value.
It's not clear what it is you are actually trying to achieve, without some example data, and the desired end result.
To write a multi-table UPDATE statement, I first write a SELECT statement that returns the primary (or unique) keys of the tables that I am going to update, along with the current values of the columns to be updated, and expressions that return the new values that are going to be assigned to the columns
Based on the SQL in the question, it looks like you might want two joins, something like this:
SELECT ...
FROM table_a a
JOIN table_b b
ON b.s_id = a.id
JOIN table_c c
ON c.id = b.j_id
WHERE a.percent = 100
ORDER BY ...
(We don't know anything about the cardinality of the columns and relationships, whether those are one-to-one, one-to-many, zero-or-one-to-one, etc. We're just guessing.)
To evaluate and test the query, I'd include the primary keys of the tables. I'm going to guess id is the primary key of (the unfortunately named) Table_A and Table_C. And guess that the tuple (j_id,s_id) is a UNIQUE KEY in Table_B.
I will also include the column to be updated (to show the current value), and an expression that returns the new value to be assigned to the column.
Something like this:
SELECT a.id AS `a__id`
, a.percent AS `a__percent`
, b.j_id AS `b__j_id`
, b.s_id AS `b__s_id`
, c.id AS `c__id`
, c.b AS `c__b_old`
, b.b AS `c__b_new`
FROM table_a a
JOIN table_b b
ON b.s_id = a.id
JOIN table_c c
ON c.id = b.j_id
WHERE a.percent = 100
ORDER
BY c.id
, a.id
I would test that, and make sure it's returning the rows from Table_C that I want to update, and that the value returned for the c__b_new expression is the value that I want to assign to the b column in Table_C.
Once I get the SELECT statement working correctly (and only after I get it working correctly), I convert that to a multitable UPDATE.
Just replace the SELECT ... FROM part with the keyword UPDATE.
And before the WHERE clause, add a SET clause that does the assignment of the new value to the column. (I use the same expression I used in the SELECT list to return the new value.)
UPDATE table_a a
JOIN table_b b
ON b.s_id = a.id
JOIN table_c c
ON c.id = b.j_id
SET c.b = b.b
WHERE a.percent = 100
That's just an example of how I go about writing a multi-table UPDATE. There is no guarantee that this statement is going to work for what you need. Again, it's not clear what you are trying to achieve; the specification is too vague; so we're only guessing.

Sum the same value with different condition

Ok, the title is cryptic but I don't know how to sintetize it better.
I have a series of expensive similar SELECT SUM queries that must be executed in sequence.
Example:
SELECT SUM(t2.Field)
FROM Table1 AS t1
INNER JOIN (
SELECT Field FROM Table2
WHERE [list of where]
) AS t2 ON ti.ExtKey = t2.Key
WHERE t1.TheValue = 'Orange'
SELECT SUM(t2.Field)
FROM Table1 AS t1
INNER JOIN (
SELECT Field FROM Table2
WHERE [list of where]
) AS t2 ON ti.ExtKey = t2.Key
WHERE t1.TheValue = 'Apple'
And so on.
I've used the nested inner join because after some test it resulted faster than a plain Join.
The rows selected for Table2 are always the same, or at least the same for session.
There's a way to group all the queries in one to speed up the execution?
I was thinking about using a material view, but this would complicate very much the design and maintenance.
I am no sure about your goal. I have a guess for you:
http://sqlfiddle.com/#!9/af66e/2
http://sqlfiddle.com/#!9/af66e/1
SELECT
SUM(IF(t1.TheValue = 'Orange',t2.Field,0)) as oranges,
SUM(IF(t1.TheValue = 'Apple',t2.Field,0)) as apples
FROM Table1 AS t1
INNER JOIN (
SELECT Field, `key` FROM Table2
) AS t2 ON t1.ExtKey = t2.`key`
# GROUP BY t1.extkey uncomment if you need it
If you can provide raw data sample and expected result that would help a lot.
I think you want a group by:
SELECT t1.TheValue, SUM(t2.Field)
FROM Table1 t1 INNER JOIN
(SELECT Field
FROM Table2
WHERE [list of where]
) t2
ON t1.ExtKey = t2.Key
GROUP BY t1.theValue;
Note that your query doesn't quite make sense, because t2 doesn't have a column called key. I assume this is an oversight in the question.
If you want to limit it to particular values, then use a WHERE clause before the GROUP BY:
WHERE t1.TheValue IN ('Apple', 'Orange', 'Pear')

3 tables and 2 left joins

Query 1:
SELECT sum(total_revenue_usd)
FROM table1 c
WHERE c.irt1_search_campaign_id IN (
SELECT assign_id
FROM table2 ga
LEFT JOIN table3 d
ON d.campaign_id = ga.assign_id
)
Query 2:
SELECT sum(total_revenue_usd)
FROM table1 c
LEFT JOIN table2 ga
ON c.irt1_search_campaign_id = ga.assign_id
LEFT JOIN table3 d
ON d.campaign_id = ga.assign_id
Query 1 gives me the correct result where as I need it in the second style without using 'in'. However Query 2 doesn't give the same result.
How can I change the first query without using 'in' ?
The reason being is that the small query is part of a much larger query, there are other conditions that won't work with 'in'
You could try something along the lines of
SELECT sum(total_revenue_usd)
FROM table1 c
JOIN
(
SELECT DISTINCT ga.assign_id
FROM table2 ga
JOIN table3 d
ON d.campaign_id = ga.assign_id
) x
ON c.irt1_search_campaign_id = x.assign_id
The queries do very different things:
The first query sums the total_revenue_usd from table1 where irt1_search_campaign_id exists in table2 as assign_id. (The outer join to table3 is absolutely unnecessary, by the way, because it doesn't change wether a table2.assign_id exists or not.) As you look for existence in table2, you can of course replace IN with EXISTS.
The second query gets you combinations of table1, table2 and table3. So, in case there are two records in table2 for an entry in table1 and three records in table3 for each of the two table2 records, you will get six records for the one table1 record. Thus you sum its total_revenue_usd sixfold. This is not what you want. Don't join table1 with the other tables.
EDIT: Here is the query using an exists clause. As mentioned, outer joining table3 doesn't alter the results.
Select sum(total_revenue_usd)
from table1 c
where exists
(
select *
from table2 ga
-- left join table3 d on d.campaign_id = ga.assign_id
where ga.assign_id = c.irt1_search_campaign_id
);

Compare 2 tables and find non duplicate entries

I have 2 tables. I want to check if columns of table 1 don't have duplicates in columns of table2.
Here is how the search should work!
If no duplicates are found, I want to get the row name from table1.
If I got you right, this is what you want.
SELECT
t1.name
FROM
Table1 t1
WHERE
t1.name
NOT IN
(
SELECT t2.name
FROM Table2 t2
JOIN t1
ON t2.name = t1.name
)
You need to specify a column (or columns) that you will use to "match" the rows, to determine whether they are "duplicates".
I'm going to assume (absent any schema information), that the column name is id.
An "anti-join" pattern is usually the best performing option:
SELECT a.id
FROM table1 a
LEFT
JOIN table2 b
ON a.id = b.id
WHERE b.id IS NULL
(Performance is dependent on a whole bunch of factors.)
Your other options are to use a NOT EXISTS predicate:
SELECT a.id
FROM table1 a
WHERE NOT EXISTS
( SELECT 1
FROM table2 b
WHERE b.id = a.id
)
Or, use a NOT IN predicate:
SELECT a.id
FROM table1 a
WHERE a.id NOT IN
( SELECT b.id
FROM table2 b
WHERE b.id IS NOT NULL
)
The generated execution plan and performance of each of these statements will likely differ. With large sets, the "anti-join" pattern (the first query) usually performs best.