Select last duplicate row in MySQL - mysql

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
)

Related

INSERT from SELECT statement, column count

Table1 has one column and table2 has three columns. The names are all unique.
INSERT INTO table2 (SELECT * FROM table1 WHERE name = 'Brian')
#1136 - Column count doesn't match value count at row 1
What is the easiest way to append NULL or empty strings to the results of the SELECT query?
I have tried this and many other variations:
INSERT INTO table2 (SELECT * FROM test WHERE name = 'Brian', '','')
INSERT INTO test2 ((SELECT * FROM test WHERE name = 'Brian') + '' , '')
The easiest way is to specify the column names in both source and target tables:
INSERT INTO table2 (col2) -- change col2 to the name of the column in table2 that will receive the values
SELECT col1 -- change col1 to the name of the column in table1
FROM table1
WHERE name = 'Brian';
All other than col2 columns in table2 will be set to null or their default values (if defined in the table's definition).
Even if col1 is the only column in table1, you should prefer SELECT col1 over SELECT *, because if you add any columns to the table SELECT * would stop working.

MySQL select the last two inserted IDs

How can I select the last two inserted IDs?
Here I explain how I could use these. This is my query:
INSERT INTO Table1 (FIELD1, FIELD2, FK_TABLE2, FIELD6)
(SELECT FIELD1, FIELD2
,(SELECT MAX(PK_Table2)
FROM Table2
)
,(FIELD4 + FIELD5) FROM Table1 WHERE FIELD3 = (
(SELECT MAX(PK_Table2)
FROM Table2) - 1
))
This should almost duplicate all records linked to the last but one record of table2, for the last record of table2.
This works right now, but only because I had not deleted a record yet.
If I delete the last record from table2 and insert another one, my generator will generate a new PK that is not the last+1.
eg: Last two IDs are: 18-19. I Delete 19 and insert another one. Now the last two IDs are 18-20. So Max(PK_Table2) will be 20 and Max(PK_Table2)-1 will be 19, but I need it to be 18.
You need to steps:
Get the max ID
Get the max ID less then that
This would be:
WHERE FIELD3 =
(
SELECT MAX(PK_Table2) FROM Table2
WHERE PK_Table2 < (SELECT MAX(PK_Table2) FROM Table2)
)
Another approch: Get the last two, then get the second last one.
WHERE FIELD3 =
(
SELECT PK_Table2
FROM (SELECT PK_Table2 FROM Table2 ORDER BY PK_Table2 DESC LIMIT 2) x
ORDER BY PK_Table2 LIMIT 1
)

How to limit the result of UNION ALL query?

I have a query like this:
select col1, col2 from table1 where col1 = ?
union all
select col1, col2 from table2 where col2 = ?
Now I need to limit the result of the above query, Now I want to know, if I use limit clause after second select, then just the result of second select will be limited or the result of both select?
Anyway, which approach is good for limiting the result of union all query?
One:
select col1, col2 from table1 where col1 = ?
union all
select col1, col2 from table2 where col2 = ?
limit ?,10
Two:
select * from
(
select col1, col2 from table1 where col1 = ?
union all
select col1, col2 from table2 where col2 = ?
) x
limit ?,10
According to MySQL manual:
To use an ORDER BY or LIMIT clause to sort or limit the entire UNION
result, parenthesize the individual SELECT statements and place the
ORDER BY or LIMIT after the last one.
Hence, you can use:
(select col1, col2 from table1 where col1 = ?)
union all
(select col1, col2 from table2 where col2 = ?)
LIMIT ?, 10
Using a sub-query should also work, but can't be more efficient in comparison to the above query.
The first is better from a performance perspective. The second materializes the subquery, which is additional overhead.
Note: You are using limit without an order by, so the results may not be consistent from one execution of the query to the next.
You should be using order by, which probably makes it irrelevant which version you use (because the order by needs to read and write the data anyway).

Add "on duplicate key update" clause to insert into query

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;

NOT IN AND IN condition mysql

I have SQL query design as below.
SELECT (THIS ITEMS)
FROM (TABLES)
WHERE(SOME CONDITION) AND NOT IN (CONDITION) AND IN (CONDITION)
But not getting proper output as required, as 'IN' condition isn't wrking properly
You need a column to compare to. Proper syntax is (note the column_expression):
SELECT <select_list>
FROM <table_expression>
WHERE <column_expression> [NOT] IN (<comparison_list>)
For example,
SELECT col1, col2
FROM tab
WHERE col3 IN ('yes', 'no')
AND col4 NOT IN ('no', 'maybe')
Note you can also use a single-column result set instead of a static comparison list, as in:
SELECT col1, col2
FROM tab
WHERE col3 IN (SELECT filterValues FROM table2)
but it is much more optimal to use an EXISTS clause for this case:
SELECT col1, col2
FROM tab
WHERE EXISTS (SELECT 1 FROM table2 WHERE filterValues = col3)
You may need brackets around certain conditions.
Example 1:
Select all persons who are active and have an invoice
Person->Invoice (1 to Many)
SELECT * FROM person WHERE active=1 AND person_id IN (SELECT person_id FROM invoice)
Example 2:
Select all person who are active, do not have a cat, and have an invoice
SELECT * FROM person WHERE active=1 AND person_id NOT IN (SELECT person_id FROM people_with_cats) AND person_id IN (SELECT person_id FROM invoice)