What I would like to do is the following:
SELECT SUM(ABS(`number_x` - `number_y`)) AS `total_difference` FROM `table`
Where the table is as follow:
id | number_x | number_y
1 | 4 | 2
2 | 3 | 2
3 | 2 | 4
So the answer should be:
(4 - 2 = 2) + (3 - 2 = 1) + (2 - 4 = 2) = 5
Can I do this in MySQL and how?
Thanks!
The query you posted should work with no problem:
SELECT SUM(ABS(`number_x` - `number_y`)) AS `total_difference`
FROM `table`
Or if you want to write it with a subquery like so:
SELECT SUM(diff) AS `total_difference`
FROM
(
SELECT Id, ABS(number_x - number_y) diff
FROM TableName
) t
SELECT SUM(ABS(`number_x` - `number_y`)) AS `total_difference` FROM `table`
OR You can write other way, but i'll prefer above only
SELECT ABS(SUM(number_x) - SUM(number_y)) AS total_difference FROM table
Related
This question already has answers here:
Sort the rows according to the order specified in WHERE IN clause
(6 answers)
Closed last year.
I want to fetch records from a table using the sequence provided in "IN" operator
select * from table where id in (10, 5, 30)
I want this result
ID | Name
10 | Xyz
5 | Abc
30 | Jkl
but it is actually showing this result
ID | Name
5 | Abc
10 | Xyz
30 | Jkl
IN cannot be used to determine the order of results. You need to use some kind of row value constructor:
select *
from (
select 10 as id, 1 as sort union all
select 5, 2 union all
select 30, 3
) as custom_list
join your_table on custom_list.id = your_table.id
order by custom_list.sort
Table:2018
No Email
1 Lilly#gmail.com
2 brens#gmail.com
3 susan#gmail.com
4 resh#gmail.com
Table:2017
No Email
1 chitta#gmail.com
2 resh#gmail.com
3 brens#gmail.com
4 minu#gmail.com
Table:2016
No Email
1 brens#gmail.com
2 chitta#gmail.com
3 lisa#gmail.com
4 monay#gmail.com
5 many#gmail.com
Table:2019
No Email
1 brens#gmail.com
2 chitta#gmail.com
3 rinu#gmail.com
4 emma#gmail.com
I need to perform Union of tables 2018,2017,2016 without any duplicate emails minus table 2019 ,Result should look like
RESULT
No Email
1 Lilly#gmail.com
2 susan#gmail.com
3 resh#gmail.com
4 minu#gmail.com
5 lisa#gmail.com
6 monay#gmail.com
7 many#gmail.com
Minus operation is not available in Mysql.
select a.*from(select *from y2018 union select *from y2017 where not exists(select *from y2018 where y2018.email=y2017.email ) union select *from y2016 where not exists(select *from y2018 where y2018.email=y2016.email ))a LEFT OUTER JOIN y2019 b on a.email=b.email where b.email is null ;
This gives the result but does not eliminate the duplicates in (2017 union 2016)
some one please help me
I need to perform Union of tables 2018,2017,2016 without any duplicate
emails minus table 2019
The most easy to simulate/emulate minus/expect is using NOT IN()
Query
SELECT
(#ROW_NUMBER := #ROW_NUMBER + 1) AS 'No'
, unique_email.Email
FROM (
SELECT
DISTINCT
years_merged.Email
FROM (
SELECT
Email
FROM
y2019
UNION ALL
SELECT
Email
FROM
y2018
UNION ALL
SELECT
Email
FROM
y2017
UNION ALL
SELECT
Email
FROM
y2016
) AS years_merged
WHERE
years_merged.Email NOT IN(SELECT y2019.Email FROM y2019 )
ORDER BY
years_merged.Email ASC
) AS unique_email
CROSS JOIN (SELECT #ROW_NUMBER := 0) AS init
ORDER BY
#ROW_NUMBER ASC
Result
| No | Email |
| --- | --------------- |
| 1 | Lilly#gmail.com |
| 2 | lisa#gmail.com |
| 3 | many#gmail.com |
| 4 | minu#gmail.com |
| 5 | monay#gmail.com |
| 6 | resh#gmail.com |
| 7 | susan#gmail.com |
Yes the order is different but this is the best you can do as SQL standards defines SQL tables to be sorted orderless..
see demo
But a simulate/emulate minus/expect using ... LEFT JOIN ... ON ... WHERE .. IS NULL might optimize better vs a NOT IN()
See demo
I find a better method, creating a view and save a portion of the query in it. It helps to reduce the processing time as well.
create view vm as select *from y2018 union select *from y2017 where not exists(select *from y2018 where y2018.email=y2017.email);
SELECT a.*FROM(SELECT * FROM vm union select *from y2016 where not exists(select *from vm where vm.email=y2016.email))a LEFT JOIN y2019 b ON a.email=b.email where b.email is null;
Here 'vm' is the view
I have the following sql table:
| ID | numbers |
|----|-----------------------------|
| 1 | 1,3,19,23,28,32,39,42,60,80 |
| 2 | 1,3,18,24,29,33,40,43,61,80 |
| 3 | 1,2,3,25,30,34,41,44,62,78 |
In Numbers I have a string with 10 numbers.
I want to get all couple of two elements (and if it is possible for three, four etc) in SQL Server or MySQL.
For example for two elements:
1,3 appers in all rows (3 times)
1, 80 appears in the first and second row (2 times)
etc
I tried to split numbers from every row and insert into a temporary table and after generate combinations of 10 choose k (where k is numbers of elements in a couple) but something doesn't work. I don't know if it's the best idea.
My code in this moment: http://pastebin.com/qRjPdfay
Thanks
Yes, splitting your numbers coulmns to rows would make things easier. If you are using MySQL you could use a query like this:
CREATE TABLE mytable2 AS
SELECT
ID, SUBSTRING_INDEX(SUBSTRING_INDEX(numbers, ',', n),',',-1) AS number
FROM
mytable CROSS JOIN (SELECT 1 AS n
UNION ALL SELECT 2 AS n
UNION ALL SELECT 3 AS n
UNION ALL SELECT 4 AS n
UNION ALL SELECT 5 AS n
UNION ALL SELECT 6 AS n
UNION ALL SELECT 7 AS n
UNION ALL SELECT 8 AS n
UNION ALL SELECT 9 AS n
UNION ALL SELECT 10 AS n) d;
(this will work if all numbers contains exactly 10 numbers an no less, if there are less this query needs some improvements). Then you can count the time each number appears:
SELECT number, COUNT(*) as appears
FROM mytable2
GROUP BY number
ORDER BY appears DESC
and you can group number by the number of times they appear:
SELECT
appears, GROUP_CONCAT(number) AS numbers
FROM (
SELECT number, COUNT(*) as appears
FROM mytable2
GROUP BY number
ORDER BY appears DESC
) g
GROUP BY
appears
ORDER BY
appears DESC
(MySQL only) and the result will be like this:
| appears | numbers |
|---------|---------------|
| 3 | 3,1 |
| 2 | 80 |
| 1 | 43,23,40..... |
Please see a fiddle here.
I have a table like this:
id | val
---------
1 | abc
2 | def
5 | xyz
6 | foo
8 | bar
and a query like
SELECT id, val FROM tab WHERE id IN (1,2,3,4,5)
which returns
id | val
---------
1 | abc
2 | def
5 | xyz
Is there a way to make it return NULLs on missing ids, that is
id | val
---------
1 | abc
2 | def
3 | NULL
4 | NULL
5 | xyz
I guess there should be a tricky LEFT JOIN with itself, but can't wrap my head around it.
EDIT: I see people are thinking I want to "fill the gaps" in a sequence, but actually what I want is to substitute NULL for the missing values from the IN list. For example, this
SELECT id, val FROM tab WHERE id IN (1,100,8,200)
should return
id | val
---------
1 | abc
100 | NULL
8 | bar
200 | NULL
Also, the order doesn't matter much.
EDIT2: Just adding a couple of related links:
How to select multiple rows filled with constants?
Is it possible to have a tableless select with multiple rows?
You could use this trick:
SELECT v.id, t.val
FROM
(SELECT 1 AS id
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5) v
LEFT JOIN tab t
ON v.id = t.id
Please see fiddle here.
Yes, you can. But that will be tricky since there are no sequences in MySQL.
I assume you want just any selection, so it's:
SELECT
*
FROM
(SELECT
(two_1.id + two_2.id + two_4.id +
two_8.id + two_16.id) AS id
FROM
(SELECT 0 AS id UNION ALL SELECT 1 AS id) AS two_1
CROSS JOIN (SELECT 0 id UNION ALL SELECT 2 id) AS two_2
CROSS JOIN (SELECT 0 id UNION ALL SELECT 4 id) AS two_4
CROSS JOIN (SELECT 0 id UNION ALL SELECT 8 id) AS two_8
CROSS JOIN (SELECT 0 id UNION ALL SELECT 16 id) AS two_16
) AS sequence
LEFT JOIN
t
ON sequence.id=t.id
WHERE
sequence.id IN (1,2,3,4,5);
(check the fiddle)
It will work as combination of powers of 2 to generate consecutive table of numbers. Your values are passed to WHERE clause, so you can substitute there any set of values.
I would recommend you to use application for this case - because it will be faster. It may have some sense if you want to use this row set somewhere else (i.e. in some other queries) - but if not, it's a work for your application.
If you'll need higher values, add more rows to sequence generator, like in this fiddle.
I am trying to get the results for the query type
SELECT * FROM table WHERE id IN(2,4,6,1,1,2) ORDER BY field (id,2,4,6,1,1,2)
and I want to get results in the same order as the list including : the duplicates. The above query retains the order but cuts out duplicates. I know I can post-process the results but just wondering if there is an easier way.
Thanks
This will actually achieve what you want:
SELECT * FROM table
inner join (
select 1 as sort, 2 as value union all
select 2, 4 union all
select 3, 6 union all
select 4, 1 union all
select 5, 1 union all
select 6, 2) X on X.value=table.id
ORDER BY X.sort
How are you building the query? If you're not opposed to doing a little manual work (which you could later wrap in some code), unions should get you what you need:
select id from table where id in (1, 2, 4, 6)
union all
select id from table where id in (6, 8);
Returns:
------
| id |
|====|
| 1 |
| 2 |
| 4 |
| 6 |
| 6 |
| 8 |
------
EDIT: Actually, I don't think that helps your ordering, though. Let me play with this some more.