I have a EAV table. I want to convert this into a normal table in a single query. How can I do this?
Table A
| ID | Entity | Attribute |
+----+--------+-----------+
| 1 | AA | 5 |
| 2 | AA | 2 |
| 3 | AA | 4 |
| 1 | BB | 6 |
| 2 | BB | 5 |
Table B (intended. This has only ID as of now)
| ID | AA | BB |
+----+-----+------+
| 1 | 5 | 6 |
| 2 | 2 | 5 |
| 3 | 4 | NULL |
I tried the following:
update B join A using(ID) set b.AA=(case when Entity='AA' then Attribute end),b.BB=(case when Entity='BB' then Attribute end);
update B join A using(ID) set b.AA=(case when Entity='AA' then Attribute else AA end),b.BB=(case when Entity='BB' then Attribute else BB end);
But the table is not getting updated. Both the fields are set to NULL for all the IDs. I can write separate update queries for each Entity, but I have >100 different entities and each query takes hours to run (I have many records).
Related
I have been looking around quite a lot but I can't seem to find a solution to this problem.
I got two tables:
|---------------------|-------------------|
| ID | Value |
|---------------------|-------------------|
| 1 | NULL |
| 2 | NULL |
| 3 | NULL |
| 4 | NULL |
|---------------------|-------------------|
...
|---------------------|-------------------|
| ID | Value |
|---------------------|-------------------|
| 1 | 7 |
| 1 | 18 |
| 2 | 21 |
| 2 | 2 |
| 4 | 103 |
|---------------------|-------------------|
...
Basically what I wanna do is update the NULL-fields from the first table with the smallest value from the second table where there are matching IDs.
So that in the end it looks something like this:
|---------------------|-------------------|
| ID | Value |
|---------------------|-------------------|
| 1 | 7 |
| 2 | 2 |
| 3 | NULL |
| 4 | 103 |
|---------------------|-------------------|
...
I tired out a bunch of things but failed. Can anyone help me?
You could use a sub query:
update t1
inner join (select ID, min(Value) as minimum from t2 group by ID) tempt2 on t1.ID=tempt2.ID
set t1.value=tempt2.minimum;
Basically, you're looking up that minimum value in the second table for each ID, you call that table tempt2, and you join on that.
I have a table in a database that has several columns containing the same sort of data, these values are allowed to be null. I need to select each of the non-null values into a single column of values that care about the identity of the row from which they originated.
So, for a table that looks like this:
+---------+------+--------+------+
| Id | name | v1 | v2 |
+---------+------+--------+------+
| 1 | eko | aa | bb |
| 2 | agus | null | cc |
| 3 | eko | dd | null|
| 4 | budi | aa | null|
| 5 | siti | ff | gg |
+---------+------+--------+------+
I wish to select each of the values aa,bb,cc, etc into a single column. My result data should look like the following table.
+-------+-------+-------+
| id | name | v |
+-------+-------+-------+
| 1 | eko | aa |
| 1 | eko | bb |
| 2 | agus | cc |
| 3 | eko | dd |
| 4 | budi | aa |
| 5 | siti | ff |
| 5 | siti | gg |
+-------+-------+-------+
I am using mysql. Is there a technique for achieving this with respect to performance too?
You could just use two queries and use the union statement of the two to append the two sets:
Select id, v1 as v
From table
where v1 is not null
union all
select id, v2 as v
from table
where v2 is not null
But to make this dynamic (any number of v...) you would have to iterate over the columns. See:mysql, iterate through column names
I have two tables:
Table a:
+----+------+
| id | data |
+----+------+
| 1 | 450 |
| 2 | 500 |
| 3 | 550 |
| 4 | 600 |
| 5 | 650 |
+----+------+
Table b:
+----+------+------+
| id | a_id | note |
+----+------+------+
| 1 | 2 | 25 |
| 2 | 5 | 10 |
+----+------+------+
I need a query that returns a table that consists of every row from table a with the notes from table b. I want 0 filled in where a note isn't available on a row. I want it to look like this:
+----+------+------+
| id | data | note |
+----+------+------+
| 1 | 450 | 0 |
| 2 | 500 | 25 |
| 3 | 550 | 0 |
| 4 | 600 | 0 |
| 5 | 650 | 10 |
+----+------+------+
How do I do that?
select a.id, a.data, coalesce(b.note, 0) as note
from a
left join b on a.id = b.a_id
What are you looking for is called LEFT/RIGHT JOIN. This question will give you more details about what they are.
Assume you have a query like:
SELECT * FROM a LEFT JOIN b ON some_condition;
Then, its output will contain every row from table a, along with data from table b where the condition is met. For rows where the condition is not met, the columns with data from b will contain null.
I'm having trouble figuring out how to update the descendants/children of a row.
Example table, named test
+----+--------+------+
| Id | Parent | Val |
+----+--------+------+
| 1 | 0 | |
| 2 | 1 | |
| 3 | 1 | |
| 4 | 1 | |
| 5 | 0 | |
| 6 | 5 | |
| 7 | 6 | |
| 8 | 6 | |
| 9 | 0 | |
+----+--------+------+
What I'd like to have done is, when Val is set to something, update every row that is related to that row. For example, If I ran
UPDATE test SET Val=1 WHERE Id=5;
I want Val in the rows where the Id is 6, 7, and 8, to also be 1.
The best thing I could come up with was
UPDATE test t1
JOIN test t2 ON t1.Id = t2.Parent
JOIN test t3 ON t2.Id = t3.Parent
SET t1.Val=1, t2.Val=1, t3.Val=1 WHERE t1.Id=5;
+----+--------+------+
| Id | Parent | Val |
+----+--------+------+
| 1 | 0 | |
| 2 | 1 | |
| 3 | 1 | |
| 4 | 1 | |
| 5 | 0 | 1 |
| 6 | 5 | 1 |
| 7 | 6 | 1 |
| 8 | 6 | 1 |
| 9 | 0 | |
+----+--------+------+
This gives me what I want, but I'm afraid it's poor practice and it doesn't account for a variable depth. What can I do here? I thought a trigger may have been the answer, but that didn't seem to be possible. I got the error "Can't update table in stored function/trigger because it is already used by statement which invoked this stored function/trigger"
It's pretty awkward to handle this kind of case with MySQL, because MySQL doesn't support recursive queries.
I solve this problem by storing the hierarchy as a transitive closure, instead of the "parent_id" style you're using. See my answer to What is the most efficient/elegant way to parse a flat table into a tree?
Then you can update all descendants of a given node in the heirarchy:
UPDATE test JOIN testclosure AS c ON test.id = c.descendant
SET test.val = 1
WHERE c.ancestor = 5;
Given a join table for m-2-m relationship between booth and user
+-----------+------------------+
| booth_id | user_id |
+-----------+------------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 5 |
| 1 | 9 |
| 2 | 1 |
| 2 | 2 |
| 2 | 5 |
| 2 | 10 |
| 3 | 1 |
| 3 | 2 |
| 3 | 3 |
| 3 | 4 |
| 3 | 6 |
| 3 | 11 |
+-----------+------------------+
How can I get a distinct set of booth records that are common between a subset of user ids? For example, if I am given user_id values of 1,2,3, I expect the result set to include only booth with id 3 since it is the only common booth in the join table above between all user_id's provided.
I'm hoping I'm missing a keyword in MySQL to accompish this. The furthest I've come so far is using ... user_id = all (1,2,3) but this is always returning an empty result set (I believe I understand why it is though).
The SQL query for this will be:
select booth_id from table1 where [user_id]
in (1,2,3) group by booth_id having count(booth_id) =
(select count(distinct([user_id])) from table1 where [user_id] in (1,2,3))
If this could help you creating the MySQL query.