How to update table columns that are stored as rows? - php

I am first time trying to update plugin data in wordpress database. I am using Advanced CF7 DB plugin for storing contact form 7 data. For updating the column I dont know whether pivot is required or there is anyother way to achieve this. Have searched but found two tables using pivot. I want to update data in same table just the columns are in rows. Dont know how to do this. Data is stored in below format:
| id | cf7_id | data_id | name | value
+----+--------+---------+-----------------+------------------
| 9 | 4561 | 2 | uid | 60eabb2c20021
| 10 | 4561 | 2 | emailId | axxxxx#gmail.com
| 11 | 4561 | 2 | clicked_on_link | No
| 12 | 4561 | 2 | orderNos | Miscommunication
| 13 | 4561 | 2 | submission_id | 177
+----+--------+---------+-----------------+------------------
I want to update column clicked_on_link= Yes where uid= 60eabb2c20021. uid will be passed from url parameter.
| 11 | 4561 | 2 | clicked_on_link | Yes
I want this query in php-sql form so that I can include this in code.I have tried following query which I know is wrong but tried atleast:
update wp_cf7_vdata_entry as b1,
(select data_id,MAX(CASE WHEN name='uid' THEN value ELSE NULL END) AS
uid,
MAX(CASE WHEN name='email_id' THEN value ELSE NULL END) AS email_id,
MAX(CASE WHEN name='clicked_on_link' THEN value ELSE NULL END) AS
clicked_on_link
from wp_cf7_vdata_entry group by data_id) as b2
set b2.clicked_on_link='Yes'
where b1.data_id=b2.data_id
and b2.uid=60ea1e95190ee;

You can use join:
update wp_cf7_vdata_entry e join
wp_cf7_vdata_entry e2
on e.data_id = e2.data_id
set e2.value = 'yes'
where e.name = 'uid' and e.value = '60eabb2c20021' and
e2.name = 'clicked_on_link';
Note: I'm not sure if cf7_id is relevant for the join condition, but your code only uses data_id.

Related

MySQL get newest data of user from every table

I have 6 tables to store my user data
tbl_user_name
uuid | username | date (unix time)
-----------------------------------------
0 | lisha.s | 1489857236
1 | titami | 1485853232
2 | mathew | 1442853636 <----|> Users can change their username
3 | sandarjun | 1489857239 |> so i need to get the uuid by the
2 | mathew_kar | 1575456274 <----|> newest username which is given
tbl_user_fullname:
uuid | fullname | date (unix time)
-----------------------------------------
0 | Lisha Simonette | 1489857236
1 | Titus Amiran | 1481256345
2 | Mathew Karolina | 1489234455
3 | Sandhya Arjun | 1489857239
0 | Lisha Karolina | 1599999999
tbl_user_website:
uuid | website | date (unix time)
-----------------------------------------
0 | google.com | 1489857236
1 | titusamiran.com | 1489855234
2 | mathewk.net | 1489857432
3 | blod.sandhya.info | 1489857239
tbl_user_birthdate:
uuid | birthdate | date (unix time)
-----------------------------------------
0 | 02-05-1991 | 1489857236
1 | 05-08-1980 | 1489857123
2 | 09-09-1992 | 1489851334
3 | 17-02-1998 | 1489857239
tbl_user_follower:
uuid | follower_uuid
-----------------------
0 | 4
1 | 8
2 | 0
3 | 4
3 | 2
3 | 1
tbl_user_online:
uuid | last_seen (unix time)
-----------------------
0 | 1489855334
1 | 1589851111
2 | 1689857234
3 | 1789834539
i want to collect the uuid, the fullname, the website, the birthdate and the number of followers by a user with a given username. (i need to get the newest uuid of a username because the user can change the username).
The date column is the timestamp when they changes a value. for example in tbl_user_fullname: Lisha Simonette (uuid 0) married Mathew Karolina (uuid 2) so i neet to get the new fullname of Lisha (uuid 0) by the date column. And so on ... for tbl_user_website and tbl_user_birthdate .. even if they dont change their birthday often ;)
From the table tbl_user_online i only need the last_seen timestamp.
The value i give to the query is the username. the username should give out the uuid with which i can query the other tables.
Thank you very much for your help and sorry for my bad english ;)
The below query will resolve the question asked:
SELECT usr.uuid,
ful.fullname,
web.website,
brt.birthdate,
COUNT(fol.follower_uuid)
FROM tbl_user_name usr
JOIN tbl_full_name ful ON ful.uuid = usr.uuid
LEFT JOIN
tbl_full_name ful2 ON ful2.uuid = ful.uuid
AND ful2.time_stamp > ful.time_stamp
JOIN tbl_user_website web ON web.uuid = usr.uuid
LEFT JOIN
tbl_user_website web2 ON web2.uuid = web.uuid
AND web2.time_stamp > web.time_stamp
JOIN tbl_user_birthdate brt ON brt.uuid = usr.uuid
LEFT JOIN
tbl_user_birthdate brt2 ON brt2.uuid = brt.uuid
AND brt2.time_stamp > brt.time_stamp
JOIN tbl_user_follower fol ON fol.uuid = usr.uuid
WHERE usr.username = 'jack_2'
AND ful2.uuid IS NULL
AND web2.uuid IS NULL
AND brt2.uuid IS NULL
GROUP BY
usr.uuid,
ful.fullname,
web.website,
brt.birthdate
This query works by isolating the latest timestamp in a table that shares a common element in a row. In this case the uuid.
Here is the fiddle to see it working.
Here is a fiddle without the username filter
You have a bigger issue that you need to resolve, however. You should not be storing values like you are with timestamps.
I suggest you look into table triggers for update and insert statements. You should have a trigger set up to automatically insert an entry into an audit table that stores this information while keeping your core functioning tables small and orderly.
e.g create a table called tbl_user_name_audit. Have a trigger on tbl_user_name for updates. When a username is updated the previous value is inserted into the tbl_user_name_audit table with a before and after value as well as a timestamp and audit type (INSERT/UPDATE/DELETE).

How to select rows from MySQL table with max values

I have a table with multiple rows for each customer and and a visit_date. The visit date can be null as well.
My tables are as below:
customers:
id | name | email
1 | John Doe1 | a.b#gmail.com
2 | John Doe2 | b.c#gmail.com
3 | John Doe3 | x.y#gmail.com
store_customers
id | customer_id | store_id | email_optedin | visit_date
1 | 1 | 1 | 1 | 2015-11-30
2 | 1 | 2 | 1 | 2016-05-08
3 | 1 | 3 | 1 | null
4 | 2 | 1 | 1 | 2015-04-30
5 | 2 | 2 | 1 | 2015-08-40
6 | 2 | 3 | 1 | 2015-12-12
7 | 3 | 1 | 1 | null
8 | 3 | 2 | 1 | null
9 | 3 | 3 | 1 | null
I am trying to retrieve customers who either have not had a visit to the any of the three stores or have not visited since a specified date (e.g. 2016-04-15).
I am expecting customers 2 and 3 but not 1.
I tried this query:
select distinct * from customers
inner join store_customers on store_customers.customer_id = customers.id
where customers.email != '' and
store_customer.store_id in (1,2,3) and customers.emailStatus not in ('Unverified','Bounced','Spammed')
and
(
store_customer.email_optedin = 1
and max(store_customers.visit_date) <= '2016-04-15'
or account_customer.visit_date is null
);
This does not work. I somehow need to, for the set of store ids), I need to select customers who have either not had any visit (all nulls for visit date for the specified stores) or the if one or more visit dates are available then compare the max date to the specified date.
I found similar questions but none of the answers has worked for me, mainly because of the requirement of selecting either those customers who have no visit or if they do atleast one, then to compare the latest visit date from the set of stores in the joined table.
I am trying to do this all in one query but if that is not possible then I can break it up as well. I also do not want to change the order of joins because there are many other things added on to this query and changing the order of joins may become a problem.
I really appreciate any help that can be provided.
Regards,
Waqar
Try this query
SELECT
customers.id,
customers.name,
MAX(store_customers.visit_date)
FROM
customers LEFT JOIN store_customers on customers.id = store_customers.customer_id
GROUP BY customers.id,customers.name
HAVING MAX(store_customers.visit_date) < '2016-04-15' OR MAX(store_customers.visit_date) IS NULL

Inserting value in one column from another table mysql

school
+-----+-----------+----------+
| id | the_photo | column3 |
+-----+-----------+----------+
| 11 | NULL | abc |
| 22 | NULL | asf |
| 33 | NULL | asag |
+-----+-----------+----------+
school_images
+-----+-----------+-------+
| id | school_id | photo |
+-----+-----------+-------+
| 1 | 11 | 1 |
| 2 | 22 | 0 |
| 3 | 33 | 1 |
+-----+-----------+-------+
...
Need to insert values into the_photo column of school only if photo value = 1 for school_images like this:
School
+-----+-----------+
| id | the_photo |
+-----+-----------+
| 11 | 1 |
| 22 | NULL |
| 33 | 3 |
+-----+-----------+
Is there a simple query that can be written to do this for all rows? For one row i know how to insert it but how can i auto inert for multiple rows.
This might be what you're looking for: SELECT INTO.
Taken from the link:
INSERT INTO tbl_temp2 (fld_id)
SELECT tbl_temp1.fld_order_id
FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;
BEWARE!! This answer is good only if you want to perform the above requested action upon a new insertion. Otherwise, you will need a different strategy
you should have something like this:
Select all you values from school_images then foreach them:
foreach($result as $res) {
if($res['photo'] == 1) {
// see step 2
} else {
// see step 3
}
}
if you have the value 1 in school_photos then:
INSERT INTO school (the_photo, colum3) VALUES ($res['id'], $some_value)
if you don't have it, then perform a normal insert like you did by now.
You can also use inner join to achieve that.
Update School inner join school_images on School.id = school_images.school_id and photo=1
set the_photo = school_images.id ;
You should use an INNER JOIN to join school with school_images:
UPDATE
school INNER JOIN school_images
ON school.id = school_images.school_id
AND school_images.photo=1
SET
school.the_photo=school_images.id
UPDATE school AS s, school_images AS si SET s.the_photo = si.id WHERE s.id = si.school_id AND si.photo = 1;

MySQL struggling with a query to find similar details among products

I have a query to write and I am absolutely stumped on how to do it. Here's my situation, I am trying to provide a particular product_ID, then match all of the other product_IDs in the database that have at least the same intDescription_detail_IDs as the provided product_ID.
The relevant tables look like this:
tblproducts
=========================
product_ID | product_name
=========================
| 1 | dresser |
| 2 | bookcase |
| 3 | table |
| 4 | chair |
=========================
tbldescriptions
=========================================================================
|description_ID| intDescription_product_ID | intDescription_detail_ID |
=========================================================================
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 4 | 2 | 1 |
| 5 | 2 | 2 |
| 6 | 2 | 6 |
| 7 | 3 | 1 |
| 8 | 3 | 3 |
| 9 | 3 | 4 |
| 10 | 4 | 1 |
| 11 | 4 | 2 |
| 12 | 4 | 7 |
As an example, if I provided the product_ID "1", then I would like to return all of the product_IDs that at least have intDescription_detail_ID 1 and 2.
So, the product_IDs that should be returned are 1, 2, and 4, because all of these products have the intDescription_detail_ID of 1 and 2 among their details.
I am highly confused about how to write a query like this, so any help is greatly appreciated!
I should warn you by saying that I may have made a silly mistake here...
DROP TABLE IF EXISTS products;
CREATE TABLE products(product_ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,product_name VARCHAR(20) NOT NULL UNIQUE);
INSERT INTO products VALUES
(1,'dresser'),
(2,'bookcase'),
(3,'table'),
(4,'chair');
DROP TABLE IF EXISTS product_detail;
CREATE TABLE product_detail
(product_id INT NOT NULL
,detail_id INT NOT NULL
,PRIMARY KEY(product_id,detail_id)
);
INSERT INTO product_detail VALUES
(1,1),
(1,2),
(2,1),
(2,2),
(2,6),
(3,1),
(3,3),
(3,4),
(4,1),
(4,2),
(4,7);
SELECT DISTINCT c.product_id
FROM product_detail a
JOIN product_detail b
ON b.product_id = a.product_id
AND b.detail_id <> a.detail_id
JOIN product_detail c
ON c.product_id <> a.product_id
AND c.detail_id = a.detail_id
JOIN product_detail d
ON d.product_id = c.product_id
AND d.detail_id = b.detail_id
WHERE a.product_id = 1;
+------------+
| product_id |
+------------+
| 2 |
| 4 |
+------------+
Alternative to #Strawberry’s suggestion with JOINs this can also be done using HAVING for filtering products that have (at least) the same number of rows with the same intDescription_detail_IDs as the product the search is done for:
SELECT intDescription_product_ID
FROM tbldescriptions t1
WHERE intDescription_detail_ID IN (
SELECT intDescription_detail_ID
FROM tbldescriptions t2
WHERE t2.intDescription_product_ID = 1
)
GROUP BY intDescription_product_ID
HAVING count(*) >= (
SELECT count(intDescription_detail_ID)
FROM tbldescriptions t3
WHERE t3.intDescription_product_ID = 1
)
http://sqlfiddle.com/#!2/ce698/2
One should keep in mind though that HAVING is applied last, so that will select all products with at least one matching intDescription_detail_ID first, and filter the results based on the actual count afterwards – so depending on the size and characteristic of your data set that might not be the best performing solution.

Mysql query comma separator

I having two tables
table 1: users
| id | username |
| 1 | john |
| 2 | marry |
| 3 | deep |
| 4 | query |
| 5 | value|
and
table 2:users_2
| table_2_id | user_id |
| 1 | 2,4 |
I need required something like this
| table_2_id | username |
| 1 | marry,query |
anyone can help me for this output in mysql
Is this what you are looking ?
select
`users_2`.`table_2_id` , GROUP_CONCAT(`users`.`username`) as `usernames`
from `users_2`
inner join `users` on FIND_IN_SET(`users`.`id`,`users_2`.`user_id`)
Check output here
http://sqlfiddle.com/#!2/c498bc/3
select a.table_2_id,b.username
from users b,users_2 a
where a.table_2_id=b.id
and b.id in(a.user_id)
group by a.table_2_id
First of all, you should not store a multiple value in a single field. For table users_2, the data should be:
table_2_id user_id
1 2
1 4
After you normalized your table, you can use mysql GROUP_CONCAT() to get the result in the format you mentioned
SELECT
users_2.table_2_id,
GROUP_CONCAT(users.username) AS username
FROM
users_2
JOIN
users ON users.id = users_2.user_id
GROUP BY
users_2.table_2_id
;

Categories