Let's say I have the following table in my MySQL database:
id item value
1 Plump A
2 Apple B
3 Banana F
4 Peach K
5 Orange B
6 Cherry U
And I have this table on my computer:
id value
1 B
2 F
3 L
4 A
5 B
6 A
I want to import the table from computer and replace the values from value with the values from value where id = id without changing the values in item.
Means, I need this on my MySQL database at the end:
id item value
1 Plump B
2 Apple F
3 Banana L
4 Peach A
5 Orange B
6 Cherry A
How can I do that?
I ended up with doing the following in Apple Numbers:
Then copy and paste in something like Coda. Search replace tab characters.
Result is:
UPDATE my_table SET value = "B" WHERE id = 1;
UPDATE my_table SET value = "F" WHERE id = 2;
UPDATE my_table SET value = "L" WHERE id = 3;
UPDATE my_table SET value = "A" WHERE id = 4;
UPDATE my_table SET value = "B" WHERE id = 5;
UPDATE my_table SET value = "A" WHERE id = 6;
Now I just have to execute these SQL codes in my database. Done!
Related
Let say I have a table with 3 variable: var1, var2, var3 and another table of reference.
Now I want to create anothe variable: var4; var4 is computed from var1, var2 and var3 and the reference table.
I could create a macro to do that (for each line), but I dont know how to pass the value from the macro (a table) into a result. I wonder how can we do it by creating a function to get a value, not a macro?
I understand that if I can create a function like that (this function will include data step and proc summary), thing will be easy like:
var4 = myfunction(var1, var2, var3).
Update:
The table reference in my case is:
age range1 range2 range3
1 10 1 8
2 0 4 1
3 4 6 1
4 6 5 2
5 10 5 6
So I want my function to get like:
var4 = myfunction(var1, var2, var3), for example var1 = 2, var2 = 2, var3 = 5:
Take the sum of range2 (correspond to var1 = 2); from line 2 to line 5 (corrspond to var2= 2 and var3 = 5) and the result will be: 4 + 6 + 5 + 5.
Thanks in advance.
One solution could be to first modify the reference table to a long format with one row per age per range number, and with the accumulated range in a new variable. The sum from var2 to var3 then becomes the difference between two accumulated values, which is easier to compute in a double join:
* Define input data with parameters;
data have;
input var1 var2 var3;
datalines;
1 1 3
2 2 5
3 1 4
;
run;
* Define reference table;
data ref_table;
input age range1 range2 range3;
datalines;
1 10 1 8
2 0 4 1
3 4 6 1
4 6 5 2
5 10 5 6
;
run;
* Modify reference table to long format with accumulated ranges;
data mod_ref_table;
set ref_table;
* Calculated accumulated values of each range;
acc_range1 + range1;
acc_range2 + range2;
acc_range3 + range3;
* Output the accumulated values for each range;
range_no = 1;
acc_range = acc_range1;
output;
range_no = 2;
acc_range = acc_range2;
output;
range_no = 3;
acc_range = acc_range3;
output;
keep age range_no acc_range;
run;
* Calculate output;
proc sql;
create table want as
select a.*
,case
when a.var2 = 1 then c.acc_range
else c.acc_range - b.acc_range
end as val4
from have as a
left join mod_ref_table as b
on a.var1 = b.range_no and a.var2-1 = b.age
left join mod_ref_table as c
on a.var1 = c.range_no and a.var3 = c.age
;
quit;
Macro returning a value
OK the solution can be found here.
Anyway thanks for your support.
How can I do to get number of steps to get a sub of tree .
for example I have a table like this:
id title parent_id
1 A 0
2 B 0
3 C 1
4 F 3
5 O 3
6 D 2
7 J 6
8 T 2
9 P 8
A // 1 step
C //2 step
F //3 step
O //3 step
B //1 step
D //2 step
J //3 step
T //2 step
P //3 step
for example if I give a number like 1 (id = 1 ), it should return 1 and id=6 it should return 2 as step.
my DBMS is MySQL.
It can be a recursive stored procedure, if your tree is not very deep. Something like this (with addition of proper condition handlers), or anything of the same kind, it can be written in various ways:
DELIMITER $
CREATE PROCEDURE depth(IN n INT, OUT depth INT)
BEGIN
DECLARE parent INT DEFAULT 0;
SET max_sp_recursion_depth=255;
SELECT parent_id INTO parent FROM t WHERE id=n;
IF parent = 0 THEN SET depth = 1;
ELSE CALL depth(parent,depth); SET depth = depth + 1;
END IF;
END $
DELIMITER ;
CALL(6,#depth);
SELECT #depth;
Also, MariaDB 10.2 supports recursive CTE. It's an early beta now, so it's not good for production, but if you're only evaluating your options, you can try it out. This should work:
WITH RECURSIVE tree(id,parent_id,depth) AS
(
SELECT id, parent_id, 1 from t WHERE parent_id=0
UNION ALL
SELECT t.id, t.parent_id, depth+1 FROM t JOIN tree ON tree.id = t.parent_id
) SELECT * FROM tree WHERE id = 6;
Here is my table's (events) content. eventID is "primary key" and parentID is "foreign key" with references to events(eventsID)
self referenced table :
eventID eventName parentID appFK
1 evt1 null 2
2 evt2 1 1
3 evt3 1 1
4 evt4 null 3
5 evt5 8 3
6 evt6 null 4
7 evt7 null 1
8 evt8 null 1
and another table content (applications) like this :
appID appName
1 app1
2 app2
3 app3
4 app4
I'd like to fetch all eventIDs which are parents or not with a given appID. If a child has the given appID, i'd like to get his parentID and not himself. So the result is going to be like this with appID = 1 :
eventID eventName ParentID appFK
1 evt1 null 2 // parent event who has children with appID = 1
7 evt7 null 1 // event with no child and appID = 1
8 evt8 null 1 // parent event with appID = 1 and has a child
I tried lot of examples and read a lot of solutions here but i didn't find a problem like this. Can you help me to write the right SQL ?
thx.
Try this:
SELECT DISTINCT COALESCE(e2.eventID, e1.eventID),
COALESCE(e2.eventName, e1.eventName),
COALESCE(e2.appFK, e1.appFK)
FROM events AS e1
LEFT JOIN events AS e2 ON e1.parentID = e2.eventID AND e1.appFK = 1
WHERE (e1.appFK = 1 AND e1.parentID IS NULL) OR (e2.eventID IS NOT NULL)
The LEFT JOIN fetches parent records (e1.parentID = e2.eventID) of a child having appID = 1 (e1.appFK = 1).
The WHERE clause selects root records having appID = 1 and root records that are related to a child having appID = 1 (e2.eventID IS NOT NULL).
Demo here
I have a Table like below:
Id Name Email
1 A email1#gmail.com
2 B email1#gmail.com
3 C email1#gmail.com
4 d email2#gmail.com
5 E email3#gmail.com
6 F email3#gmail.com
Expected output(while searching from an email)
Id Name1 Name2 Name3 Email
1 A B C email1#gmail.com
How to get this result using mysql query?
using while loop you can display like you want
while($dbrow = mysql_fetch_row($dbx))
{
print("<tr>");
$col_num = 0;
foreach($dbrow as $key=>$value){
if($dbrow[$col_num] > 0)
{
print("<td>$dbrow[$col_num]</td>");
}
else
{
print("<td> </td>");
}
$col_num++;
}
print("</tr>");
}
SELECT GROUP_CONCAT(Name), Email
FROM table
WHERE 1
GROUP BY Email
You can have the Names as comma separated string, then parse it as per your need.
So I have this matrix:
E1 = [54 5 2 4;4 5 19 29;31 4 2 9; 1 3 99 34]
lets say I want to find the location of the value closest to 18.9. let A = 18.9
I would do
[r,c] = find(E1==min(min(abs(E1-A))))
This doesn't work. It returns r = "[](0x1)" and c = "[](0x1)"
however,
if I first do:
F = abs(E1-A) and then do
[r,c] = find(F==min(min(F)))
this gives r = 2 and c = 3 which is correct. 19 is the closest value and 19 lives in row 2 column 3.
Why doesnt this work then? F is simply abs(E1-A) so why can I not put abs(E1-A) in place of F in the find formula?
min(min(abs(E1-A)))
ans = 0.10000
This gives you the min over the absolute difference. Then you compare it to E1 which has absolute values. This is complete different from your second formular
[r,c] = find(F==min(min(F)))
where you comapre the minimum difference with the matrix containing the absolute of differences between E1 and A. If you replace in your second formula F with abs(E1-A) you would get
[r,c] = find(abs(E1-A)==min(min(abs(E1-A))))
Which would also work. Nevertheless I would suggest another approach:
E1 = [54 5 2 4;4 5 19 29;31 4 2 9; 1 3 99 34];
A = 18.9;
# get the index ( Column-major order) of the minimum
idx = nthargout (2, #min, abs (E1-A)(:));
# this returns 10
# convert it ro row, column
[r, c] = ind2sub (size (E1), idx)
r = 2
c = 3