insert ignore into user_login_history
(`created_at`,`updated_at`,`created_by`,
`updated_by`,`USER_ID`,`TENANT`,
`LAST_LOGIN`,`deleted`,`published`)
values(
(SELECT
a.created_at,
a.updated_at,
a.created_by,
a.updated_by,
user.id,
a.tenant,
a.created_at,
b'0',
b'1'
FROM
(SELECT audit_log_summary.*
FROM audit_log_summary, (SELECT
user, MAX(created_at) AS created_at, tenant
FROM
audit_log_summary
WHERE
audit_log_summary.REVISION_TYPE = 'LOGGED_IN'
GROUP BY user , TENANT) max_user
WHERE
audit_log_summary.user = max_user.user
AND audit_log_summary.tenant = max_user.tenant
AND audit_log_summary.created_at = max_user.created_at) a
INNER JOIN
user ON a.user = user.email));
error i am getting :
Error Code: 1136. Column count doesn't match value count at row 1
basically I have 3 tables i want to populate data in one table fetching the data from other two..
Table to be populated: user_login_history
Tables From which datas are fetched: audit_log_summary & user
You have to remove VALUES from the clause, so instead of using INSERT INTO VALUES, use INSERT INTO SELECT FROM. Maybe SELECT audit_log_summary.* you should select the needed columns only. In your select you are selecting a.created_at twice, check if it is what you want.
Maybe this will help:
insert ignore into user_login_history (`created_at`,
`updated_at`,
`created_by`,
`updated_by`,
`USER_ID`,
`TENANT`,
`LAST_LOGIN`,
`deleted`,
`published`)
(SELECT
a.created_at,
a.updated_at,
a.created_by,
a.updated_by,
user.id,
a.tenant,
a.created_at,
b'0',
b'1'
FROM
(SELECT audit_log_summary.*
FROM audit_log_summary, (SELECT
user, MAX(created_at) AS created_at, tenant
FROM
audit_log_summary
WHERE
audit_log_summary.REVISION_TYPE = 'LOGGED_IN'
GROUP BY user , TENANT) max_user
WHERE
audit_log_summary.user = max_user.user
AND audit_log_summary.tenant = max_user.tenant
AND audit_log_summary.created_at = max_user.created_at) a
INNER JOIN
user ON a.user = user.email));
Related
I have tables users (id, email), permissions (id, description) and users_permissions (user_id, permission_id, created) with many to many relation.
I need to select user with some email and assign to him all permissions from table permissions, which he does not have.
Now I am trying to assign at least all permissions, but I am getting error
Subquery returns more than 1 row
My query:
insert into `users_permissions` (`user_id`, `permission_id`, `created`)
select
(select `id` from `users` where `email` = 'user-abuser#gmail.com') as `user_id`,
(select `id` from `permissions`) as `permission_id`,
now() as `created`;
If a subquery (inside SELECT) returns more than one row, MySQL does not like it.
Another way to achieve your requirement is using CROSS JOIN between Derived Tables (subquery in the FROM clause):
INSERT INTO `users_permissions` (`user_id`, `permission_id`, `created`)
SELECT
u.id,
p.id,
NOW()
FROM
users AS u
CROSS JOIN permissions AS p
WHERE u.email = 'user-abuser#gmail.com'
Why in MYSQL by executing this SQL query 2 rows will add to table? Is this query executes two times!?;
INSERT INTO user(`usr_name`, `email`, `name`, `reg_date`, `role_id`)
(
SELECT "editor1",
"editor1#example.com",
"editor1",
"2005-12-20",
2
FROM `user`
WHERE (("admin", 3) IN (
SELECT usr_name, role_id
FROM `user`
)
AND NOT EXISTS (
SELECT usr_name, email
FROM `user`
WHERE usr_name = "editor1" OR email = "editor1#example.com"
))
)
result is here!
Apparently, two rows in user match the WHERE conditions.
You are not using the user table in the first FROM. So how about this instead:
INSERT INTO user(`usr_name`, `email`, `name`, `reg_date`, `role_id`)
SELECT t.*
FROM (SELECT 'editor1' as user_name, 'editor1#example.com as email,
'editor1' as name, '2005-12-20 as reg_date, 2 as role_id
) t
WHERE ('admin', 3) IN (SELECT usr_name, role_id
FROM `user`
) AND
NOT EXISTS (SELECT usr_name, email
FROM `user` u
WHERE u.usr_name = t.usr_name OR u.email = t.email
)
Or, better yet, but unique indexes on the fields that you don't want duplicated in the table:
create unique index idx_user_username on user(usr_name);
create unique index idx_user_email on usr(email);
Let the database protect the table. It is there to help you.
I have a table full of duplicate data, based on multiple columns. I came up with this query to find all the duplicated rows
select *
from polls
group by server_id, product_id, poll_date
having count(*) > 1;
How do I update these results and set the "updated_by" field to "admin".
I tried doing this, but it doesn't work for me :(
update polls
set updated_by='admin'
group by server_id, product_id, poll_date
having count(*) > 1;
Thanks for your help
You should be able to join your SELECT with the UPDATE.
UPDATE `polls` AS `p1`
INNER JOIN (
SELECT *
FROM `polls`
GROUP BY `server_id`, `product_id`, `poll_date`
HAVING COUNT(*) > 1
) AS `p2`
ON `p2`.`server_id` = `p1`.`server_id`
AND `p2`.`product_id` = `p1`.`product_id`
AND `p2`.`poll_date` = `p1`.`poll_date`
SET `p1`.`updated_by` = 'admin';
Of course it would be better to directly join on the primary key (if you have one).
I'm attempting to update a MySQL table to show column name 'processed' as '2' if there is duplicate entries for 'name' and 'address_1', but it's not working - as usual I think I'm just being a bit of a moron..
Here's what I'm trying
UPDATE `records`
SET `processed`='2', `count` = (SELECT COUNT(`user`)
FROM `records`
WHERE `name`<>''
AND `address_1`<>'')
WHERE `count`=> '1';
Basically, if there's more than one 'name' and 'address_1' then the 'processed' field needs updating to '2'..
You could use a query like this one to return duplicated names and addresses:
SELECT name, address_1, COUNT(*) cnt
FROM records
GROUP BY name, address_1
HAVING COUNT(*)>1
and then join this query to the records table, and update the column processed to 2 where the join succeeds:
UPDATE
records INNER JOIN (SELECT name, address_1, COUNT(*) cnt
FROM records
GROUP BY name, address_1
HAVING COUNT(*)>1) duplicates
ON records.name = duplicates.name
AND records.address_1=duplicates.address_1
SET
`processed`='2',
`count` = duplicates.cnt
WHERE
records.`name`<>''
AND records.`address_1`<>''
Does MySQL support common table expressions? For example in Oracle there's the WITH clause? :
WITH aliasname
AS
( SELECT COUNT(*) FROM table_name )
SELECT COUNT(*) FROM dept,aliasname
SELECT t.name,
t.num
FROM TABLE t
JOIN (SELECT c.id,COUNT(*) 'num1'
FROM TABLE1 c
WHERE c.column = 'a'
GROUP BY c.id) ta1 ON ta1.id = t.id
JOIN (SELECT d.id,COUNT(*) 'num2'
FROM TABLE2 d
WHERE d.column = 'a'
GROUP BY d.id) ta2 ON ta2.id = t.id
One way is to use a subquery:
SELECT COUNT(*)
FROM dept,
(
SELECT COUNT(*)
FROM table_name
) AS aliasname
Note that the , between the two tables will cross join the two tables the same as in your query you posted. IF there is any relation between them you can JOIN them instead.
No, MySQL does not support Common Table Expressions (CTE). So instead of using WITH tablealias as (....), you will have to do a subquery.
For example,
WITH totalcount AS
(select userid, count(*) as tot from logins group by userid)
SELECT a.firstname, a.lastname, b.tot
FROM users a
INNER JOIN
totalcount b
on a.userid = b.userid
can be re-written in MySQL as
SELECT a.firstname, a.lastname, b.totalcount
FROM users a
INNER JOIN
(select userid, count(*) as tot from logins group by userid) b
on a.userid = b.userid
So let's talk about WITH clause .
WITH clause and INNER JOIN otherwise JOIN are a kind of same , but WITH clause gives you much more latitude especially in WHERE clause ;
I am going to make a view that'll get values like count of users , user name and etc.
First (Creating our tables users and inserted_users) :
inserted_users table :
CREATE TABLE users (id BIGINT(10) AUTO INCEREMENT PRIMARY KEY , name VARCHAR(50))
users table :
CREATE TABLE users (id BIGINT(10) AUTO INCEREMENT PRIMARY KEY , name VARCHAR(50) , gender TINYINT(1))
Second (Inserting some values to work with) :
users table :
INSERT INTO users (name,gender) VALUES ('Abolfazl M' , 1)
I don't want to insert into inserted_users by query , but I want to add a TRUGGER which will insert data automatically to users_inserted table before data be inserted into users table.
Third (Creating trigger add_uinserted) :
DELIMITER $$
CREATE TRIGGER IF NOT EXISTS add_uinserted BEFORE INSERT ON users FOR EACH ROW
BEGIN
IF NEW.name <> '' THEN
INSERT INTO users_inserted (name) VALUES (NEW.name);
ELSE
INSERT INTO users (name,gender) VALUES ('Unknown',NEW.gender);
INSERT INTO users_inserted (name) VALUES ('Unknown');
END IF;
END$$
DELIMITER ;
Run the query and the trigger will be created and at last let's create a view to give us result from a query having WITH clause .
CREATE VIEW select_users AS
WITH GetCAll AS (
SELECT u1.id As Uid ,COUNT(u1.name) AS CnAll FROM users u1
)
SELECT u1.name AS NAME,CASE
WHEN s1.gender = 1 THEN "MALE"
WHEN s1.gender = 0 THEN "FEMALE"
ELSE "UNKNOWN"
END AS GENDER,CASE
WHEN u1.id = gca.Uid THEN "INSERTED TO users_inserted"
ELSE "NOT INSERTED TO users_inserted"
END AS INSERTED,gca.CnAll FROM GetCAll AS gca INNER JOIN users u1;
After you query got ran the view will be created and by calling the view select_users the data will be shown
Last step (calling the select_users view) :
SELECT * FROM select_users
Thanks for taking a look at my answer , and that's it !!