I have table A and B with many to one associations (b contains fk_a). Let's assume the sample tables are as follows:
A:
id first
1 sample
2 sample
B:
id fk_a type value
1 1 som thing
2 1 oth other
3 2 som thing
4 2 oth any
I would like the "first" column in table A to be unique, and I would like to achieve it by having to:
desired A:
id first
1 sample-thing-other
2 sample-thing-any
Is it possible to use pure MYSQL to use UPDATE and CONCAT on table A to obtain desired update?
It would be easy if I had everything in one table, I could just write
UPDATE A
SET first = CONCAT(first, value)
but unfortunately I have many-to-one association and I am not sure if it is even possible in such case.
I do not have the instance of mysql, and not test it. use the group_concat
UPDATE A, (SELECT fk_a, GROUP_CONCAT(value SEPARATOR '-') as concat_value FROM B GROUP BY fk_a) AS t
SET A.first = CONCAT(A.first, '-', t.concat_value)
WHERE A.id = t.fk_a;
Group_Concat is your friend.
But may I remind you of first normal form?
Related
Hi, just registered to ask this since I did not find answers after some research :
My table my_table has several columns, but only two matter here : id (integer, primary key, ...) and children (varchar that contains one or several {"number":"number"} as seen in the example below)
id | children
0 | {"0":"0"}
1 | {"1":"1"} {"2":"2"} {"3":"3"}
2 | {"2":"2"}
3 | {"3":"3"}
4 | {"4":"4"}
5 | {"5":"5"} {"6":"6"}
6 | {"6":"6"}
You can see that for any choosen row, the column children will always contain at least one occurence of {"number":"number"} where 'number' is equal to the value of column id of this row.
Sometimes it contains more than one occurence of {"number":"number"} with numbers of other rows' id.
I would like to build a SQL query that returns all rows :
where there is only one occurence of {"number":"number"} in the children column
and for each row, verify that the value 'number' in {"number":"number"} is equal to the row's id value.
I tried :
SELECT * FROM my_table
WHERE children=CONCAT('{"', my_table.id, '":"', my_table.id, '"}')
This returns nothing obviously...
I'm still searching but I guess some more experienced users will have a solution :)
EDIT1 : I wrote '=' instead of ':' in my query and never noticed it xD Thank you. The query is now correct and working as intended.
Select all records with an ID mismatch (you had an equal sign where it must be a colon):
SELECT *
FROM my_table
WHERE children NOT LIKE CONCAT('%{"', my_table.id, '":"', my_table.id, '"}%');
Select all records with only one pair:
SELECT *
FROM my_table
WHERE children NOT LIKE '{%{%';
Combine the two somehow if you want a cobined result :-)
I agree with very bad db design notice.
your problem is maybe very simple - see the change in concat function
SELECT * FROM my_table
WHERE children=CONCAT('{"', my_table.id, '":"', my_table.id, '"}')
Your method should work. There must be some other characters that you are missing.
Here is another method:
where children like '%{%' and
children not like '%{%{%' and
children like concat('%"', id, '":%') and
children like concat('%:"', id, '"%')
This is just comparing each section of the pattern.
You might also try:
WHERE children LIKE CONCAT('%{"', my_table.id, '":"', my_table.id, '"}%') AND
children NOT LIKE '%{%{%';
The most likely problem are spaces (or other characters) at the beginning or end of the string. This allows those, but doesn't allow multiple items in the list.
I have Two tables in mysql database and I want to compare two columns each of them in a different table first table name "oc_product_option_value" has column:
product_option_value_id
20
21
22
23
50
100
and second table "oc_cart" has cuolomn
option
{"20":"228","24":"229"}
I want compare two table and select data from first table where "product_option_value_id" in second table.
I tried:
SELECT * FROM oc_product_option_value
WHERE product_option_id IN
(SELECT REPLACE(REPLACE(REPLACE(REPLACE(OPTION,'{',''),'}',''),':',','),'"','')
as `option` FROM `oc_cart`)
and no result
* columns Structure
"product_option_value_id" is int
"option" is TEXT
Heum.. Not sure that it will do what you expect but I think it's a first step:
1/ Returns only rows wich have a matching value in second table (oc_cart)
SELECT *
FROM oc_product_option_value acpoa
JOIN oc_cart acc ON acc.option REGEXP concat('"', acpoa.product_option_value_id, '"');
Be careful about naming a column with a reserved MySQL word (option)
EDIT :
2/ If you want to display a "result" (final_kept_column) after this comparison in order to display "value_id" or "option" even if there's no matching value in oc_cart, you can try someting like this :
SELECT *,
CASE WHEN acc.option IS NULL
THEN acpoa.product_option_value_id
ELSE 0
END AS final_kept_column
FROM oc_product_option_value acpoa
LEFT JOIN oc_cart acc ON acc.option REGEXP concat('"', acpoa.product_option_value_id, '"');
Hope this help
I have a table with a SET-field where several of the options can be selected. I want to select all rows where at least one of the options I specify is set.
The options are: A, B, C and D
Row 1: A,B
Row 2: A,C
Row 3: C
Row 4: D
I specify A and C, so the rows returned should be 1, 2 and 3
Any ideas?
You could use FIND_IN_SET, you could use LIKE:
With FIND_IN_SET, you would do something like:
SELECT * FROM myTable WHERE FIND_IN_SET('A', set_column_name)>0;
Read more about FIND_IN_SET here.
Live DEMO with the above.
With LIKE
SELECT * FROM myTable WHERE set_column_name LIKE '%A%';
This will search the entire column for the specified letter.
Read more about LIKE here.
Live DEMO with the above.
You can also use set_column_name = 'A' for single exact entries
i have a varchar field with the content like these:
a,b,c,d
e,d,a,c
b,q,d,e
i need to do a query that select only the rows with the field that has elements equals with an input string.
ex
input: c,a
rows selected:
a,b,c,d
e,d,a,c
is possible without use the OR (field like '%a%' OR field like '%c%') ?
thanks
Yes, you can use...
WHERE
myField LIKE '%a%' AND myField LIKE '%c%'
However, this does sound like you've got a nasty field in your SQL.
Normally, you would use a link-table to specify this kind of information:
Table1
id
otherdata...
Table2
id
letter
LinkTable
Table1Id
Table2Id
So in LinkTable you would have many entries that link your records. So instead of storing 'a,b,c,d' in a field, you have four link records:
Table1Id Table2Id
1 1 (a)
1 2 (b)
1 3 (c)
1 4 (d)
Yes but you need a trick: Create a second column which contains the same value but sorted:
a,b,c,d
a,c,d,e
b,d,e,q
Now, you can query for %a%c%
This won't work if the query string can be a substring of any unwanted value. If this is the case, you need quotes:
"a","b","c","d"
"a","c","d","e"
"b","d","e","q"
and query for %"a"%"c"%
I have read quite a few selcet+update questions in here but cannot understand how to do it. So will have to ask from the beginning.
I would like to update a table based on data in another table. Setup is like this:
- TABLE a ( int ; string )
ID WORD
1 banana
2 orange
3 apple
- TABLE b ( "comma separated" string ; string )
WORDS TEXTAREA
0 banana -> 0,1
0 orange apple apple -> BEST:0,2,3 ELSE 0,2,3,3
0 banana orange apple -> 0,1,2,3
Now I would like to for each word in TABLE a append ",a.ID" to b.WORDS like:
SELECT id, word FROM a
(for each) -> UPDATE b SET words = CONCAT(words, ',', a.id) WHERE b.textarea like %a.word%
Or even better: replace the word found in b.textarea with ",a.id" so it is the b.textarea that ends up beeing a comma separeted string of id's... But I do not know if that is possible.
Tried this but not working. But I think I am getting closer:
UPDATE a, b
SET b.textarea =
replace(b.textarea,a.word,CONCAT(',',a.id))
WHERE a.word IN (b.textarea)
ORDER BY length(a.word) DESC
I ended up doing a work-a-round. I exported all a.words to excel and created an update for each row like this:
UPDATE `tx_ogarktiskdocarchive_loebe` SET `temp_dictionay` = replace(lower(temp_dictionay) , lower('Drygalski’s Grønlandsekspedition'), CONCAT(',',191));
Then I pasted the aprox 1000 rows into ans sql file and executed it. Done.
I had to do "a cleaner double post" of this one to get the answer.
A solution can be put together based on this manual:
http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html#function_group-concat
GROUP_CONCAT will make a comma separated string based on the fileds it shall CONCAT. Perfect. And regarding the preferred solution with no dublicates in the result there is this example in the manual that will filter out dublicates using DISTINCT inside the GROUP_CONCAT:
mysql> SELECT student_name,
-> GROUP_CONCAT(DISTINCT test_score
-> ORDER BY test_score DESC SEPARATOR ' ')
-> FROM student
-> GROUP BY student_name;