Mysql Update based on value and select query - mysql

I want to make a UPDATE on tb_usermeta using one query, having meta_id, meta_key's and meta_value's. This is possible?
tb_usermeta:
+----+---------+-----------+------------+
| id | meta_id | meta_key | meta_value |
+----+---------+-----------+------------+
| 1 | 1 | user_nome | user 1 |
| 2 | 1 | user_fone | 99999 |
| 3 | 2 | user_nome | user 2 |
| 4 | 2 | user_fone | 88888 |
+----+---------+-----------+------------+
Ex: Data:
meta_id = 1, meta_key = user_nome, meta_value = user changed
meta_id = 1, meta_key = user_fone, meta_value = 696969
tb_usermeta after update:
+----+---------+-----------+-------------+
| id | meta_id | meta_key | meta_value |
+----+---------+-----------+-------------+
| 1 | 1 | user_nome | user changed|
| 2 | 1 | user_fone | 696969 |
| 3 | 2 | user_nome | user 2 |
| 4 | 2 | user_fone | 88888 |
+----+---------+-----------+-------------+

Consider the following...
DROP TABLE IF EXISTS eav;
CREATE TABLE eav
(entity INT NOT NULL
,attribute VARCHAR(12) NOT NULL
,value VARCHAR(20) NOT NULL
,PRIMARY KEY(entity,attribute)
);
INSERT INTO eav VALUES
(1,'user_nome','user 1'),
(1,'user_fone','99999'),
(2,'user_nome','user 2'),
(2,'user_fone','88888');
UPDATE eav
SET value = CASE attribute WHEN 'user_nome' THEN 'user changed'
WHEN 'user_fone' THEN '696969'
END
WHERE entity = 1;
SELECT * FROM eav;
+--------+-----------+--------------+
| entity | attribute | value |
+--------+-----------+--------------+
| 1 | user_nome | user changed |
| 1 | user_fone | 696969 |
| 2 | user_nome | user 2 |
| 2 | user_fone | 88888 |
+--------+-----------+--------------+
It would be nice to do this with a view - but I think MySQL would consider the fact that you're updating two things at once 'an update to multiple underlying tables', which is not allowed.

Related

Filter table rows linked to another table via pivot table on basis of where clauses acting on second table

+--------------+
| paintings |
+--------------+
| id | title |
+----+---------+
| 1 | muzelf1 |
| 2 | muzelf2 |
| 3 | muzelf3 |
+----+---------+
+----------------------------------------+
| tags |
+----------------------------------------+
| id | type | name |
+----+-----------------+-----------------+
| 1 | painting_medium | oil_painting |
| 2 | painting_style | impressionistic |
| 3 | painting_medium | mixed_media |
| 4 | painting_medium | watercolours |
| 5 | painting_style | mixed_media |
| 6 | painting_style | photorealistic |
+----+-----------------+-----------------+
+---------------------------+
| paintings_tags |
+---------------------------+
| id | painting_id | tag_id |
+----+-------------+--------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 4 |
| 4 | 3 | 2 |
| 5 | 3 | 1 |
+----+-------------+--------+
sql
CREATE TABLE paintings (
id integer AUTO_INCREMENT PRIMARY KEY,
title text
);
INSERT INTO paintings(id,title) VALUES
(1,'muzelf1'),(2,'muzelf2'),(3,'muzelf3');
CREATE TABLE tags (
id integer AUTO_INCREMENT PRIMARY KEY,
name text,
type text
);
INSERT INTO tags(id,name,type) VALUES
(1,'oil_painting','painting_medium')
,(2,'impressionistic','painting_style')
,(3,'mixed_media','painting_medium')
,(4,'watercolours','painting_medium')
,(5,'mixed_media','painting_style')
,(6,'photorealistic','painting_style');
CREATE TABLE paintings_tags (
id integer AUTO_INCREMENT PRIMARY KEY,
painting_id integer,
tag_id integer
);
INSERT INTO paintings_tags(id,painting_id,tag_id) VALUES
(1,1,1)
,(2,1,2)
,(3,2,4)
,(4,3,2)
,(5,3,1);
Find all the paintings with [{tags.type="painiting_medium", tags.name="oil_painitng"},{tags.type="painiting_style", tags.name="impressionistic"}].
+-----------------------------------+
| Expected Output |
+-----------------------------------+
| id | painting_title | painting_id |
+----+----------------+-------------+
| 1 | muzelf1 | 1 |
+----+----------------+-------------+
| 2 | muzelf3 | 3 |
+----+----------------+-------------+
Here is something I tried doing using bookShelf ORM and knex query builder.
Painting.query(function (qb) {
qb.innerJoin('painting_tags','paintings.id','painting_tags.painting_id')
.innerJoin('tags','painting_tags.tag_id','tags.id')
.where(qb => {
tagFilters.forEach(filter => {
qb.where('tags.type',filter.type).andWhere('tags.name',filter.name)
})
});
});
The above only works if the tag filters array has only one element. But I need it to work for all the filters in the array.
What would a raw query look like for the above? And how can I convert the same to work using ORM and query builder?
Here's one idea:
SELECT p.id painting_id
, p.title
, MAX(CASE WHEN t.type = 'painting_medium' THEN t.name END) medium
, MAX(CASE WHEN t.type = 'painting_style' THEN t.name END) style
FROM paintings p
JOIN paintings_tags pt
ON pt.painting_id = p.id
JOIN tags t
ON t.id = pt.tag_id
GROUP
BY p.id;
+-------------+---------+--------------+-----------------+
| painting_id | title | medium | style |
+-------------+---------+--------------+-----------------+
| 1 | muzelf1 | oil_painting | impressionistic |
| 2 | muzelf2 | watercolours | NULL |
| 3 | muzelf3 | oil_painting | impressionistic |
+-------------+---------+--------------+-----------------+
You could filter this as a subquery (or using HAVING) but, unless the data set was vast, I would be inclined to do the filtering in a bit of javascript.

MySQL split keyword with space automatically

I'm having a below table called members
+----+--------+--------+-------+--+
| id | name | gender | state | |
+----+--------+--------+-------+--+
| 1 | Peter | M | 1 | |
+----+--------+--------+-------+--+
| 2 | Sally | F | 1 | |
+----+--------+--------+-------+--+
| 3 | Martin | M | 0 | |
+----+--------+--------+-------+--+
Then, my query is
SELECT * FROM `member` WHERE `id` = '1 3';
MySQL returned | 1 | Peter | M | 1 | |.
However, I expect that it would return nothing because there should be no record with id = '1 3'.
How can I prevent this?
Try to use BINARY
select * from member where BINARY id = '1 3';

How to make record to be table title

I have this table and its data
----------------------------
| ID | NAME | TYPE | VALUE |
----------------------------
| 1 | A | YES | 10000 |
| 2 | B | NO | 100 |
| 3 | A | NO | 300 |
----------------------------
I wonder how to get data in sql like this :
-----------------------------
| ID | NAME | YES | NO |
-----------------------------
| 1 | A | 10000 | 300 |
| 2 | B | NULL | 100 |
-----------------------------
Please help
You need to pivot the data to do that.
select MIN(ID) as ID, NAME ,
Max(Case when TYPE = 'Yes' then VALUE END) as `Yes`
Max(Case when TYPE = 'No' then VALUE END) as `No`
From Yourtable
Group by NAME
Note: This assumes there are only two possible values(Yes&No) present in TYPE column.

not able to select all records for a particular id?

I have a table in SQL as given below: I need to select all records for a particular user_id:
mysql> select * from matusermeta limit 10;
+----------+---------+----------------------+---------------------------------+
| umeta_id | user_id | meta_key | meta_value |
+----------+---------+----------------------+---------------------------------+
| 1 | 1 | first_name | sandeep |
| 2 | 1 | last_name | kumar |
| 3 | 1 | nickname | sk4222 |
| 4 | 1 | description | |
| 5 | 1 | rich_editing | true |
| 6 | 1 | comment_shortcuts | false |
| 7 | 1 | admin_color | fresh |
| 8 | 1 | use_ssl | 0 |
| 9 | 1 | show_admin_bar_front | true |
| 10 | 1 | matcapabilities | a:1:{s:13:"administrator";b:1;} |
+----------+---------+----------------------+---------------------------------+
I am using this query "select * from wp_usermeta group by user_id"
+----------+---------+------------+------------+
| umeta_id | user_id | meta_key | meta_value |
+----------+---------+------------+------------+
| 1 | 1 | first_name | sandeep |
| 58 | 4 | first_name | test |
+----------+---------+------------+------------+
not all the records are showing for a particular id
If you want to select record of all userid in you table use:
SELECT * FROM [wp_usermeta] WHERE user_id IN (SELECT user_id FROM [wp_usermeta])
If you want to get record of specific userid use:
SELECT * FROM [wp_usermeta] WHERE user_id IN ('1','2','95','1204')
you are grouping by user_id not selecting, if you want select all records for a particular user_id, try this:
select * from wp_usermeta where user_id=your_particular_id
select * from wp_usermeta where user_id = Your_ID
You can the use the above code to fetch data for a Particular UserID
select * from wp_usermeta where user_id IN ( Your_ID1, Your_ID2, Your_ID3)
You can the use the above code to fetch data for any number of UserID

SQL Insert by from another table through a reference table

I've got three tables in MySQL: wp_usermeta, directory_department, and directory_departmentmemebership
Directory_departmentmembership
| employee_id|department_id|
|:-----------|------------:|
| 1 | 2 |
| 2 | 1 |
| 3 | 3 |
directory_department
| department_id|department_name|
|:----------- |--------------:|
| 1 | Deans |
| 2 | MBA |
| 3 | Fiance |
wp_usermeta has:
| employee_id| meta_key | meta_value |
|:-----------|--------------:|:------------:|
| 1 |department_id | 2 |
| 2 |department_id | 1 |
| 3 |department_id | 3 |
| 1 |department_name| |
| 2 |department_name| |
| 3 |department_name| |
How I can I reference directory_department to insert the correct department_name based off of the department_id value in the meta_value field?
You can use a SQL function to get the right name for each id...
CREATE FUNCTION [dbo].[fn_department](#id INT)
RETURNS VARCHAR(300)
AS
BEGIN
declare #department_name varchar(300)
select #department_name = department_name from directory_department where department_id = #id
RETURN #department_name
END
--And call it like this...
INSERT INTO wp_usermeta (id,department_name)
select id, dbo.fn_department(id) as department_name