I want to copy the latest information from table 1 into table 2.
For the ID i used
insert into Table2(ID) (Select ID FROM Table2). That was not a problem.
CL1 contains the oldest data.
CL3 contains the newest data. So CL2 is between.
Insert into was probably the easiest way to copy the ID from Table1 to Table2
my problem with MySQL is the following.
Table 1
ID | CL1 | CL2 | CL3
A | 1 | 2 | 3
B | 1 | 2 | NULL
C | 1 | 2 | 3
D | 1 | NULL| NULL
E | 1 | 2 | 3
Table 2
ID | CLX
A |
B |
C |
D |
E |
Result should be:
Table 2
ID | CLX
A | 3
B | 2
C | 3
D | 1
E | 3
use GREATEST().
Assuming that CL1 is not nullable, and CL3 cannot have value unless CL2 is filled up.
INSERT INTO table2(ID, CLX)
SELECT ID, GREATEST(CL1, COALESCE(CL2, CL1), COALESCE(CL3, CL1))
FROM table1
SQLFiddle Demo
Thank you,
Coalesce was the function I need for my queries.
`Select ID, COALESCE(CL3,CL2,CL1) as latest from table1`
Related
I have a table with multiple records have the same ID but different values. I want copy records from other table to this table. I want to update if record is null to the minimum position, or insert into the next position if the value does not exist.
Here is my Target table:
ID | Position | Value
1 | 1 | A
2 | 1 | B
2 | 2 | null
2 | 3 | null
2 | 4 | C
3 | 1 | A
4 | 1 | D
4 | 2 | B
Source table:
ID | Value
1 | C
2 | N
3 | B
4 | D
5 | A
6 | null
7 | B
Wanted result table:
ID | Position | Value
1 | 1 | A
1 | 2 | C
2 | 1 | B
2 | 2 | N
2 | 3 | null
2 | 4 | C
3 | 1 | A
3 | 2 | B
4 | 1 | D
4 | 2 | B
5 | 1 | A
7 | 1 | B
My query is:
MERGE Target AS T
USING (SELECT S.ID, MAX(E.POS) AS PosMax, MIN(E.POS) as PosMin, S.Value
FROM Source S
LEFT OUTER JOIN Target E ON S.ID = E.ID
WHERE S.Value IS NOT NULL AND E.Value IS NULL
GROUP BY S.ID, S.Value) AS SC
ON T.ID = SC.ID
WHEN MATCHED AND SC.Value IS NOT NULL AND EG.Value IS NULL AND T.POS = SC.PosMin
THEN
UPDATE SET
EG.Value = SC.Value
WHEN NOT MATCHED AND SC.Value IS NOT NULL
THEN
INSERT (ID, Position, Value)
VALUES (SC.D, ISNULL(SC.PosMax, 0) + 1, SC.Value);
This only updates the null value with the minimum position and insert the value if there is not exist ID. If the ID existed. It will not insert because the Match T.ID = SC.ID.
Example of ID 3, It does not inser value B in position 2.
Does anyone have different approach or strategy? Or I have to write a second query to insert if the ID is the same and value not.
Thanks,
Jay
I think your ON needs the position as well.
ON T.ID = SC.ID and T.pos=SC.minpos.
And the subquery to build SC should be an inner join. You don't want records if you don't have matching values in target.
There are two tables
A
ENO | VALUE | YMD
1 | 3 | 190308
1 | 10 | 190309
1 | 5 | 190310
B
ENO | TARGET |
1 | 10 |
We want to update the TARGET column of table B to the most recent date with the value "VALUE".
I want to change the result of the B table as follows.
B
ENO | TARGET |
1 | 5 |
What should I do?
You can try below -
update tableB A
join
(select * from tableA x where ymd in (select max(ymd) from tableA x1 where x.eno=x1.eno)
)B on A.eno=B.eno
set A.target=B.target
I have three tables
Table a
+-----+-------+
| aid | value |
+-----+-------+
| 1 | A |
| 2 | B |
| 3 | C |
| 4 | D |
+-----+-------+
Table b
+-----+------+
| bid | name |
+-----+------+
| 1 | A |
| 2 | B |
| 3 | C |
+-----+------+
Table ba (mapping of table a and table b)
+-----+-----+
| bid | aid |
+-----+-----+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 3 | 2 |
| 1 | 3 |
| 2 | 3 |
| 2 | 4 |
+-----+-----+
From these tables I want a query like
SELECT aid, mapped('true'-if(aid exist in ba) 'false'-otherwise)
FROM a
JOIN b
JOIN ba
WHERE bid=1
to get a result from where I can generate a list
(when bid=1)
A-mapped
B-not mapped
C-mapped
D-not mapped
(when bid=2)
A-mapped
B-not mapped
C-mapped
D-mapped
(when bid=3)
A-mapped
B-mapped
C-not mapped
D-not mapped
Right now I am generating the list in a while loop for all the rows of table 'a' and inside the loop a query is executed for each iteration to check the existence in table 'ba'.
I think this is supposed to be table b independent:
SELECT CONCAT_WS('-', a.value, IF(ba.aid IS NULL, "-not mapped", "-mapped"))
FROM a LEFT JOIN ba ON a.aid = ba.aid AND ba.bid = 1
ORDER BY a.aid
Note: I took "a" table as the base table since your samples included all values from "a" table.
This is a tricky question, but the difficult part is in figuring out how to formulate the query. Once that is out of the way, it is downhill from there. One approach is to use a cross join between the A and B tables to obtain all possible mappings. Then LEFT JOIN to the mapping table to determine which pairs are being mapped and which are not. Try the following query:
SELECT tb.bid, ta.value,
CASE WHEN ba.bid IS NOT NULL THEN 'mapped' ELSE 'not mapped' END AS label
FROM tb INNER JOIN ta -- cross join to obtain all bid/aid pairs
LEFT JOIN ba -- to determine which pairs are mapped/not mapped
ON ta.aid = ba.aid AND tb.bid = ba.bid
ORDER BY tb.bid, ta.value
Demo here:
SQLFiddle
I am sure this would be easy to google if I knew the right words to use, but I've tried and not come up with anything: apologies if this is a common question on SO.
I have one table which lists a set of records which can be one of 4 types.
table_1:
+-------+------------+------+
| id | value | type |
+-------+------------+------+
| 1 | x | 1 |
| 2 | y | 1 |
| 3 | z | 2 |
| 4 | a | 3 |
+-------+------------+------+
I have another table which references the id of this table and stores data
table_2:
+-------+------------+------+
| id | table_1_id |value |
+-------+------------+------+
| 1 | 4 | A |
| 2 | 2 | B |
| 3 | 3 | C |
| 4 | 2 | D |
+-------+------------+------+
I want to write a query that effects:
"Find all the records from table 1 which are of type 1, take the id's of those records, and find all the records in table 2 where 'table_1_id' which match one of that set of ids."
In the above very oversimplified table example that would result in the query returning records with ids 2 and 4 in table 2
Sounds like your looking for IN:
select *
from table2
where table_1_id in (select id from table1 where type = 1)
Or perhaps you could JOIN the tables:
select t2.*
from table2 t2
join table1 t1 on t2.table_1_id = t1.id
where t1.type = 1
Joining the tables could result in duplicate records. Depends on your needs.
SELECT t1.value,t1.type,t2.value FROM table1 t1,table2 t2 WHERE t1.id = t2.table_1_id AND t1.type = 1;
I have table A
| id | Name |
_________________________
| 1 | ABC |
_________________________
| 2 | BCD |
_________________________
Table B
| id | a_id | Status | timestamp |
__________________________________________________________
| 1 | 1 | 1 | timestamp |
__________________________________________________________
| 2 | 1 | 2 | timestamp |
__________________________________________________________
| 3 | 1 | 3 | timestamp |
__________________________________________________________
| 4 | 2 | 1 | timestamp |
__________________________________________________________
In above example I only want to pick
| name | a_id | Status | timestamp |
__________________________________________________________
| BCD | 2 | 1 | timestamp |
So with any record that has ONLY and ONLY latest STATUS as 1, I want to pick that record.. If the LATEST STATUS is 2 or 3, I don't want ot pick them...
If possible I don't want to use sub-query because I am using Codeigniter which doesn't really like subqueries.
Please help
So that will be:
SELECT
A.name,
B.*
FROM
(SELECT
a_id,
MAX(`timestamp`) AS max_timestamp
FROM B
GROUP BY a_id) AS latest
LEFT JOIN B
ON
B.a_id=latest.a_id
AND
B.`timestamp`=latest.max_timestamp
LEFT JOIN A
ON B.a_id=A.id
WHERE
B.status=1
As for subquery - I doubt you can retrieve desired information without that in single query. That is because you need to use row set, which is a result of grouping by one column, in reference to another column. And so you need to group that first, and then apply JOIN to result row set.
Thanks to #Strawberry for pointing to this article, I figured a way to do it for this example.
select a.name
,b1.a_id
,b1.status
,b1.`timestamp` AS b1Time
FROM TableA a
JOIN TableB b1 ON b1.a_id = a.id
LEFT JOIN TableB b2 ON b2.a_id = b1.a_id AND b1.`timestamp` < b2.`timestamp`
WHERE b2.`timestamp` IS NULL
AND b1.status = 1
See this Fiddle.