I have one main table (t1)
id value group
------------------------------
5 22 1
6 55 1
7 18 2
8 11 2
And a cache table (t2)
id value group
------------------------------
1 12 1
2 30 1
3 18 2
4 11 2
The main table auto-increments, so everytime data is saved, the table is cleared and new ids are created, going up each time.
I need to update t2.id with t1.id so they are matching.
Required result for cache table(t2):
id value group
------------------------------
5 12 1
6 30 1
7 18 2
8 11 2
Attempt1:
UPDATE t1, t2 SET t1.id=t2.id WHERE t1.id < t2.id ORDER BY id ASC
Attempt2:
UPDATE t1, t2 SET t1.id = t2.id WHERE t1.id IS < MIN(t2.id) ORDER BY t1.id ASC
Attempt3:
UPDATE t1
INNER JOIN (
SELECT
MIN(t1.id) AS ID
FROM t1
GROUP BY ID) m ON t1.ID = m.ID
INNER JOIN t2 ON t1.ID = t2.ID
My attempt, try and let me know:
Update cache t2
set t2.id = t2.id +
(select min(t1.id)-min(t2.id) from main t1, cache t2);
EDIT:
If you could do two step query, its much easier.
DECLARE diffValue INTEGER;
SELECT min(t1.id)-min(t2.id) into diffValue from main t1, cache t2;
UPDATE cache t2 set t2.id = t2.id + diffValue;
You can't use joins in update syntax.
Firstly delete all records in the table:
DELETE * FROM t2;
Then write the new data in it:
INSERT INTO t2
(t2.id, t2.value, t2.group)
SELECT t1.id, t1.value, t1.group FROM t1
Is this what u wanted?
Related
I have 2 access tables that contain partially similar data, one being more enriched than the other.
The idea here is to join the two tables by the fields id and num and to get from the table T2 the num that are not in the table T1
T1:
id
num
1
34
3
51
7
23
T2:
id
num
status
1
34
done
1
79
done
1
39
done
3
51
done
7
23
done
Expected result:
id
num
status
1
79
done
1
39
done
Under access I read on internet that there is no MINUS operator like under MySQL, so I tried with EXCEPT but the query takes a long time (stopped after 10min)
So I tried this:
SELECT T2.*
FROM T2 LEFT JOIN T1 ON (T1.id =T2.id)
WHERE T1.num IS NULL AND ( (T2.status LIKE 'done') );
The problem now is, I don't have all the records that are in T2 but not in T1
You can use RIGHT JOIN. And I recommend to do not use "LIKE" in this case because this is slow. You can just use the = operator. So your query will be:
SELECT t2.id, t2.num, t2.status
FROM t1
RIGHT JOIN t2
ON t1.id = t2.id
AND t1.num = t2.num
WHERE t1.num IS NULL
AND t2.status = 'done';
In case all column names you want to join are identic in both tables, you can join more simple:
SELECT t2.id, t2.num, t2.status
FROM t1
RIGHT JOIN t2
USING (id,num)
WHERE t1.num IS NULL
AND t2.status = 'done';
I don't like this, but it's shorter. At the end, your concrete query depends on your personal "taste".
There is a lot of variants.
SELECT t2.*
FROM t2
LEFT JOIN t1 USING (id, num)
WHERE t1.id IS NULL
AND t2.status = 'done'
SELECT *
FROM t2
WHERE NOT EXISTS ( SELECT NULL
FROM t1
WHERE (t1.id, t1.num) = (t2.id, t2.num) )
AND status = 'done'
There are more variants...
What of these (or maybe some another) variants is the most effective? this depends on the tables definitions and data statistic.
You're missing a condition on the join:
SELECT T2.*
FROM T2
LEFT JOIN T1
ON T1.id = T2.id
AND T1.num = T2.num
WHERE T1.num IS NULL
AND T2.status LIKE 'done';
Check it here.
Here are 2 tables.
Table 1
id value
1 3
2 2
3 3
4 1
5 4
6 3
Table 2
id
1
3
4
How do I get the ids that are in Table 2 which have the max value in Table 1?
Output:
id
1
3
I already tried the following to get the max value, but I cannot figure out how to use it in a single query to get the matching rows. Because I think I need to select from the same table I just inner joined.
select max(table1.value)
from table2
inner join table1 on table1.id = table2.id;
Here is one method:
select t2.id
from (select t2.*, rank() over (order by value desc) as seqnum
from table2 t2 join
table1 t1
on t2.id = t1.id
) t
where seqnum = 1;
Or, an alternative that puts all the ids on one row:
select group_concat(t2.id) as ids
from table2 t2 join
table1 t1
on t2.id = t1.id
group by t1.value
order by t1.value desc
limit 1;
You have a couple of options available without using window functions:
You can use a WHERE clause to select only id values that have a value equal to the MAX(value) from your query and an id that is in Table2:
SELECT t1.id
FROM Table1 t1
WHERE value = (
SELECT MAX(t1.value)
FROM Table2 t2
JOIN Table1 t1 ON t1.id = t2.id
)
AND id IN (SELECT id FROM Table2)
You can JOIN your query to Table1 and Table2 again, matching the value in Table1 and the id in Table2:
SELECT t1.id
FROM (
SELECT MAX(t1.value) AS max_value
FROM Table2 t2
JOIN Table1 t1 ON t1.id = t2.id
) t
JOIN Table1 t1 ON t1.value = t.max_value
JOIN Table2 t2 ON t2.id = t1.id
In both cases the output is
id
1
3
Demo on SQLFiddle
Too low to comment but from the SQL statement you gave, you just need to add the tableid in your select parameters.
select table2.id, max(table1.value)
from table2
inner join table1 on table1.id = table2.id;
Example:
Table 1:
id name
1 sim
2 sam
3 jas
Table 2
key age
1 10
1 20
2 40
3 10
Table 3:
id rating
2 7
2 6
3 8
3 7
1 9
Now, what I need is
number of rows that were grouped using group by in both the tables i.e table A and table B.
i.e
select t1.id, count(t2.key) as a, count(t3.id) as b
FROM
table1 t1
LEFT JOIN
table2 t2
ON
t1.id = t2.key
LEFT JOIN
table3 t3
ON
t1.id = t3.id
GROUP BY t1.key, t2.id
Result I expect:
id a b
1 2 1
2 1 2
3 1 2
You're getting duplicates because you're creating a cross product between all 3 tables. Use COUNT(DISTINCT) to filter out the duplicates.
select t1.id, count(DISTINCT t2.age) as a, count(DISTINCT t3.rating) as b
FROM table1 t1
LEFT JOIN table2 t2 ON t1.id = t2.key
LEFT JOIN table3 t3 ON t1.id = t3.id
GROUP BY t1.id
I have the 2 following tables t1, t2 with values,
t1 t2
1 4
2 2
3 3
Now I want to output
1
4
How can I get this output in select query ?
This will get you each item from t1 that is not present in t2, and each item in t2 that is not present in t1:
select t1.id from t1
left join t2 on t2.id = t1.id
where t2.id is null
union all
select t2.id from t2
left join t1 on t1.id = t2.id
where t1.id is null
(I have assumed that the field name in each table is named id just for the sake of being able to write a query against the tables.)
Another way would be:
select coalesce(t1.id, t2.id)
from t1
full outer join t2 on t2.id = t1.id
where t1.id is null or t2.id is null
Another way. Just COUNT them.
This works if the values are unique per table
SELECT
CombinedValue
FROM
(
SELECT t1 AS CombinedValue FROM t1
UNION ALL
SELECT t2 FROM t2
) foo
GROUP BY
CombinedValue
HAVING
COUNT(*) = 1
If not unique per table
SELECT
CombinedValue
FROM
(
SELECT DISTINCT t1 AS CombinedValue FROM t1
UNION ALL
SELECT DISTINCT t2 FROM t2
) foo
GROUP BY
CombinedValue
HAVING
COUNT(*) = 1
you can use Joins in MySql to proceed and to obtain result.
this will help you
http://www.techrepublic.com/article/sql-basics-query-multiple-tables/1050307
In Mysql
Table
Id AA BBB
A 45 123
B 52 120
C 40 135
How would I get
B_A 7
A_C 5
First would need to sort by BBB Asc
then minus 52-45.
B_A concatenate B and A
How Do you add/substract form previous row in SQL?
If I needed to have seperate cols for B then A, How Would I add this.
SELECT concat(t1.id , '_', t2.id, ' ', t1.aa - t2.aa )
FROM table t1
INNER JOIN (SELECT Max(t2.id) prev_id,
t1.id
FROM table t1
INNER JOIN table t2
ON t1.id > t2.id
GROUP BY t1.id) prev
ON t1.id = prev.id
INNER JOIN table t2
ON t2.id = prev.prev_id