MySQL find pairs in the same column - mysql

I have a table that looks something like this:
id
id_dlry
0
12345.67
1
12345-68
2
12345
3
12345-67
I need to find pairs in column id_dlry where id's numbers are the same, but the sign changes from '.' to '-'
I added another temporary column to the table, where I can identify the sign like this:
update products set check_sign =
(case
when id_dlry REGEXP '[0-9]{5}[.][A-Z0-9]+' THEN '1'
when id_dlry REGEXP '[0-9]{5}[-][A-Z0-9]+' THEN '2'
else '0'
end);
so it looks like this:
id
id_dlry
check_sign
0
12345.67
1
1
12345-68
2
2
12345
0
3
12345-67
2
Now I would like to create another table only with pairs of records like "12345.67" and "12345-67", so it might look like this:
id
id_dlry
check_sign
0
12345.67
1
3
12345-67
2
I tried using inner join but I got stuck.

You don't need the new column. Use count(*) over(partition by replace(id_dlry, '.', '-')):
select id, id_dlry
from
(select id,
id_dlry,
count(*) over(partition by replace(id_dlry, '.', '-')) cnt
from products) t
where cnt > 1;
Fiddle

Related

How to simulate a N-dimension INTERSECT with generic SQL

Here is an example of 2 extract from the same table:
SELECT source_id
FROM table_cust_string_value
WHERE cust_string_id=2 AND VALUE LIKE '%TATA%';
SELECT source_id
FROM table_cust_string_value
WHERE cust_string_id=4 AND VALUE LIKE '%TUTU%';
They give 2 sets of source_id.
Right. Now if I need an intersect of those with MySQL (where INTERSECT does not exist) I found this way:
SELECT DISTINCT source_id
FROM (
SELECT source_id
FROM table_cust_string_value
WHERE cust_string_id=2 AND VALUE LIKE '%TATA%'
) t1
INNER JOIN (
SELECT source_id
FROM table_cust_string_value
WHERE cust_string_id=4 AND VALUE LIKE '%TUTU%'
) t2
USING (source_id);
but what if I need to do this from N sets ?
I can't find a solution + I'm worried about the perf. of doing it this way
You can use a grouping approach. Depending on what indexes you have available this might work out better.
SELECT source_id
FROM table_cust_string_value
WHERE cust_string_id IN ( 2, 4 )
GROUP BY source_id
HAVING MAX(CASE WHEN cust_string_id = 2 AND VALUE LIKE '%TATA%' THEN 1 END) = 1
AND MAX(CASE WHEN cust_string_id = 4 AND VALUE LIKE '%TUTU%' THEN 1 END) = 1

How to aggregate this simple SQL?

I have a table like this:
ID Value Key
0 ValA 0
1 ValB 0
2 ValC 1
4 ValD 0
5 ValE 1
Apart from the table itself, I am also interested in the first ID with Key==1. I could use the following query to find it:
SELECT Key FROM MyTable WHERE Key=1 ORDER BY ID ASC LIMIT 1
Now, I'd like to combine the query to a regular SELECT, so that I have all the aggregated information in one go.
My following attempt failed, I tried:
SELECT
ID,
Value,
Key,
(SELECT Key FROM MyTable WHERE Key=1 ORDER BY ID ASC LIMIT 1 AS FirstKeyIs1)
FROM MyTable
How should I rewrite my query? The expected behaviour would have FirstKeyIs1 be 2. The goal is eventually filter out the IDs with a key property before 2.
ID Value Key FirstKeyIs1
0 ValA 0 2
1 ValB 0 2
2 ValC 1 2
4 ValD 0 2
5 ValE 1 2
If your database supports window functions, you can do:
select
t.*,
min(case when key = 1 then id end) over() firstKeyIs1
from mytable t
Otherwise, your approach using a subquery is OK. You just need to move the column alias out of the subquery - and presumably, you want to return the id rather than the key:
select
t.*,
(select id from mytable where key = 1 order by id limit 1) firstKeyIs1
from mytable
Or you can use aggregation in the subquery:
select
t.*,
(select min(id) from mytable where key = 1) firstKeyIs1
from mytable

Dynamically creating columns from row data using Select in Bigquery

Background
I want to rename my case statement in sql select statement dynamically.
Eg:
SELECT (case when id= x.id then x.sums end) x.id
as (select id,count(*) sums from table
group by id) x
what i want the output is list of columns created ,with Labels as distinct id's from "id" column.
However,this variable x.id is not dynamically outputing values,rather i get output a single column x.id.
Eg:
Columns in table...
id---c1----c2
1----x1---x2
2----x2----x3
3----x4----x5
columns expected after running query...
1-----2----3
but actual o/p column is::
x.id
Query
Any ideas,how to generate columns dynamically using select query,please correct me ,if i am wrong.
Below is for BigQuery!
Please note: your expectations about output column names are not correct!
Column name cannot start with digit - so in below example - i will be using id_1, id_2 and id_3 instead of 1, 2 and 3
SELECT
SUM(CASE WHEN id = 1 THEN 1 END) AS id_1,
SUM(CASE WHEN id = 2 THEN 1 END) AS id_2,
SUM(CASE WHEN id = 3 THEN 1 END) AS id_3
FROM YourTable
Above example assumes you know in advance your IDs and there are very few of them so it is not a big deal to write manually few numbers of lines with SUM(...) for each id
If this is not a case - you can first generate above query programmatically by running below query
SELECT 'SELECT ' +
GROUP_CONCAT_UNQUOTED(
'SUM(CASE WHEN id = ' + STRING(id) + ' THEN 1 END) AS id_' + STRING(id)
)
+ ' FROM YourTable'
FROM (
SELECT id FROM (
SELECT * FROM YourTable GROUP BY id ORDER BY id
)
as a result - you will get string like below
SELECT SUM(CASE WHEN id = 1 THEN 1 END) AS id_1,SUM(CASE WHEN id = 2 THEN 1 END) AS id_2,SUM(CASE WHEN id = 3 THEN 1 END) AS id_3 FROM YourTable
So, now just copy it and paste into Query Editor and run it
you can see similar example here - https://stackoverflow.com/a/36623258/5221944

how to find the number of consecutive repeats

So I'm trying to write a mysql script to find the number of consecutive repeats in 'value' column of this table.
id value result
-- ----- ------
1 1 0
2 1 1
3 2 0
4 3 0
5 3 1
So in this case I want get the value 2
Get the next value using user variables,
GROUP so consecutive values more than 2 are not counted again,put all in a subquery,and use a simple CASE to increment the value you need in case value=next value.Add salt and pepper.
SELECT SUM(CASE WHEN y.value=y.next_value THEN #var+1 ELSE #var END) consecIds
FROM
(SELECT t.id, t.value, next_id, n.value next_value
FROM
(
SELECT t.id, t.value,
(
SELECT id
FROM table1
WHERE id > t.id
ORDER BY id
LIMIT 1
) next_id
FROM table1 t,(SELECT #var:=0)x
) t LEFT JOIN table1 n
ON t.next_id = n.id
GROUP BY t.value,n.value)y
FIDDLE
SELECT COUNT(DISTINCT column_name) FROM table_name;
DISTINCT will erase duplicated repetitions from specified column in result.
COUNT will count the rows in result.
The COUNT(DISTINCT column_name) function returns the number of distinct values of the specified column.

mysql count total of muliple columns

hi i have a table as follow:
user table
id val1 val2 val3
1 2 3 2
2 0 0 1
i would like to know how to count value from columns val1,val2,val3 where id = 1 ? which means
for id = 1 total would be 7 and for id = 2 total would be 1. Most of SO example count the entire columns for all ids.My solution as follow seems not get preferred result
select count(*) as tot
from (
select val1 as total from user
where id=1
union
select val2 as total from user
where id=1
union
select val3 as total from user
where id=1
) as x
Thanks for help.
You can simply add the columns together:
SELECT val1 + val2 + val3 FROM user WHERE id = 1
See it on sqlfiddle.
UPDATE
To exclude NULL values, use MySQL's IFNULL() function:
SELECT IFNULL(val1,0) + IFNULL(val2,0) + IFNULL(val3,0) FROM user WHERE id = 1
See it on sqlfiddle.
It looks like you need to sum the column values for each user id. This will do:
select id, coalesce(val1, 0) + coalesce(val2, 0) + coalesce(val3, 0)
from user
Notice that coalesce is a SQL ANSI defined function, thus, it will work on other DBMSs as well. You can use IFNULL(), but that will only work in MySQL.