I'm starting with a query like this:
insert into summary ( col1, col2, Total )
select col1, col2, count(col4) as total from importdata
where col1 = 'abc' and col4 in ('1A', '2A')
group by col1, col2
order by col1, col2
and I haven't been able to determine how the correct 'on duplicate' clause. The clause I think I need is
on duplicate key update total=count(col4)
and I've placed it as the very last line in the query and as the line after the where clause, but both generated errors. Is my clause even correct and where does it need to go?
(Worst case I can use 'insert ignore', but I think doing the update would be better.)
You can't use COUNT or other group functions in the ON DUPLICATE KEY UPDATE clause. What you can do instead is this:
INSERT INTO summary ( col1, col2, Total )
SELECT col1, col2, count(col4)
FROM importdata
WHERE col1 = 'abc' AND col4 IN ('1A', '2A')
GROUP BY col1, col2
ORDER BY col1, col2
ON DUPLICATE KEY UPDATE Total = VALUES(Total)
This says, if there is a duplicate key, instead of inserting a new row just set the column total to the value you would have inserted in Total. Note that I got rid of the as total -- that would have caused problems as you already have a column named Total, and the names are case-insensitive.
You cannot use functions for the duplicate key update, however, you could create a variable and then use that variable.
INSERT INTO summary (col1, col2, Total)
select col1, col2, #totalCount := count(col4) as Total from importdata
where col1 = 'abc' and col4 in ('1A', '2A')
group by col1, col2
order by col1, col2
) ON DUPLICATE KEY UPDATE Total = #totalCount;
Related
Supposed I have an ORDER BY that is derived by a SELECT statement:
...
WHERE col1 = ...
ORDER BY (SELECT CASE .. END) // - will return col2 or col3 both of which are in the same table as column 1.
Will the following indices be of use or does using the SELECT makes them useless?
INDEX (col1, col2)
INDEX (col1, col3)
SELECT Duplicate row item from MySQL table using
SELECT * FROM `table` GROUP BY `col1`,`col2` Having COUNT(`col1`)>1 and COUNT(`col2`)>1
Actual result
The above query return first duplicate entry. from above data row 1 and row 7 contains duplicate field in same column(col1, col2).
But I need to Get last duplicate entry. Highlighted duplicate row
Expected Result
I need to get last duplicate entry.
How do you define the last duplicate? In a database table, records are not inhenrently ordered, and you did not tell which column we should use for ordering.
If you want to order by col3, then you can just use aggregation, like so:
select col1, col2, max(col3) -- or min(col3)
from mytable
group by col1, col2
-- having count(*) > 1
-- uncomment the above line if you want to see only records for which a duplicate exists
If you have some other column that you want to order with, say id, then you can filter with a correlated subquery
select col1, col2, col3
from mytable t
where id = (
select max(id) from mytable t1 where t1.col1 = t.col1 and t1.col2 = t.col2
)
I was having trouble determining a possible unique key in a poorly defined table. The table had 5000 rows. I selected distinct on the fields I thought might be a unique key.
select count(distinct col1, col2)
from tab1;
The result was 4980 records. Then I checked the 20 records and found that the values for col2 where null, but adding col3 should give me uniqueness.
select count(distinct col1, col2, col3)
from tab1;
The result was still 4980. What the? So I changed the query to this.
select col1, col2, col3, count(*)
from tab1
group by col1, col2, col3
having count(*) > 1;
With this I got zero rows, so col1, col2, and col3 are unique. So what was wrong with the first three column query? I tried this.
select count(distinct col1, coalesce(col2, ''), col3)
from tab1;
This returned 5000 records.
It is likely that the multiple fields are being concatenated together in one field in the engine, and concatenating col1, NULL, col3 is resulting in NULL and that is why it is acting this way. But, the result seems to break the NULL standards that MySQL seems to want to follow. Is this a MySQL bug?
The manual specifically says that COUNT(DISTINCT expr [,expr...])
Returns a count of the number of rows with different non-NULL expr values.
which is the behaviour you are seeing.
Lets say we have a table (1):
id | col1 | col2
And another table (2):
id | col3
Task is to insert all col3 distinct values to col1 at the same time populating col2 with random integer value
A couple of solutions here.
This uses a sub query to return the distinct values of col2.
INSERT INTO table1 (id, col1, col2)
SELECT NULL, col2, FLOOR(RAND()*(1000))+1
FROM
(
SELECT DISTINCT col2
FROM table2
)
The following abuses the GROUP BY clause to only generate rows for distinct values of col2. While this should be OK on a default install of MySQL, it might not work depending on the options set up for your installation and also probably wouldn't work in other flavours of SQL.
INSERT INTO table1 (id, col1, col2)
SELECT NULL, col2, FLOOR(RAND()*(1000))+1
FROM table2
GROUP BY col2
My problem is i have an insert that updates the query on duplicate key and it is like the one below:
INSERT INTO TABLE
(COL1, COL2, COL3 , ETC...)
SELECT
COLA1, COLA2, COUNT(1) , ETC...
FROM TABLE2
WHERE 'CONDITION'
GROUP BY COL1, COL2, COL3
ON DUPLICATE KEY UPDATE COL1=VALUES(COLA1), COL3=COUNT(1)
THIS QUERY RETURNS AN ERROR: General error: 1111 Invalid use of group function SQL
COL1, COD2, COL3 ARE COMPLEX KEY.
Try this:
INSERT INTO TABLE(COL1, COL2, COL3, ETC...)
SELECT COLA1, COLA2, COUNT(1), ETC...
FROM TABLE2
WHERE 'CONDITION'
GROUP BY COL1, COL2, COL3
ON DUPLICATE KEY UPDATE COL1 = VALUES(COL1), COL3 = VALUES(COL3);
That is, refer to the names in the values1 statement, not the expressions in the select statement.