How to set mysql datediff result into row list - mysql

I would like to ask you guys about something about DateDiff in MySQL.
for example, here is some code of mysql datediff.
select datediff('2015-10-11', '2015-10-15') as Diffdate
and the result would be
| DiffDate |
------------
| 4 |
------------
so, my question is, how do I make the Diffdate result into some kind of row numbers from 1 to the result of diffDate?
this is the result that I want.
| DiffDate |
------------
| 1 |
| 2 |
| 3 |
| 4 |
------------
thank you in advance

The trick is first to select numbers from 1 to 31:
select n.x from
(Select 1 x
union select 2 x
union select 3 x
...
union select 31 x) n ,
(select datediff('2015-10-15', '2015-10-11') as Diffdate) d
where n.x <= d.Diffdate
I the example above should datediff('2015-10-11', '2015-10-15') is -4: that's why i have exchanged the args order.

Related

How to get maximum appearance count of number from comma separated number string from multiple rows in MySQL?

My MySQL table having column with comma separated numbers. See below example -
| style_ids |
| ---------- |
| 5,3,10,2,7 |
| 1,5,12,9 |
| 6,3,5,9,4 |
| 8,3,5,7,12 |
| 7,4,9,3,5 |
So my expected result should have top 5 numbers with maximum appearance count in descending order as 5 rows as below -
| number | appearance_count_in_all_rows |
| -------|----------------------------- |
| 5 | 5 |
| 3 | 4 |
| 9 | 3 |
| 7 | 2 |
| 4 | 2 |
Is it possible to get above result by MySQL query ?
As already alluded to in the comments, this is a really bad idea. But here is one way of doing it -
WITH RECURSIVE seq (n) AS (
SELECT 1 UNION ALL SELECT n+1 FROM seq WHERE n < 20
), tbl (style_ids) AS (
SELECT '5,3,10,2,7' UNION ALL
SELECT '1,5,12,9' UNION ALL
SELECT '6,3,5,9,4' UNION ALL
SELECT '8,3,5,7,12' UNION ALL
SELECT '7,4,9,3,5'
)
SELECT seq.n, COUNT(*) appearance_count_in_all_rows
FROM seq
JOIN tbl ON FIND_IN_SET(seq.n, tbl.style_ids)
GROUP BY seq.n
ORDER BY appearance_count_in_all_rows DESC
LIMIT 5;
Just replace the tbl cte with your table.
As already pointed out you should fix the data if possible.
For further details read Is storing a delimited list in a database column really that bad?.
You could use below answer which is well explained here and a working fiddle can be found here.
Try,
select distinct_nr,count(distinct_nr) as appearance_count_in_all_rows
from ( select substring_index(substring_index(style_ids, ',', n), ',', -1) as distinct_nr
from test
join numbers on char_length(style_ids) - char_length(replace(style_ids, ',', '')) >= n - 1
) x
group by distinct_nr
order by appearance_count_in_all_rows desc ;

Select pair numbers in SQL Query

Database:
+------------+
| Number |
+------------+
| 0050000235 |
+------------+
| 5532003644 |
+------------+
| 1122330505 |
+------------+
| 1103220311 |
+------------+
| 1103000011 |
+------------+
| 1103020012 |
+------------+
To select numbers having pair of "0" 3 times I tried:
SELECT * FROM numbers
WHERE Number LIKE "%00%00%00%"
OR Number LIKE "%00%0000%"
OR Number LIKE "%0000%00%"
OR Number LIKE "0000%00%"
OR Number LIKE "%00%0000"
OR Number LIKE "00%0000%"
OR Number LIKE "%0000%00"
OR Number LIKE "%0000%00"
OR Number LIKE "%000000%"
OR Number LIKE "000000%"
OR Number LIKE "%000000"
This results me:
0050000235
But the way I am using, I think it's not a clean method.
Question How to fetch numbers having 3 pairs in it with clean SQL query?
The result will be:
0050000235, 5532003644, 1122330505, 1103220311 & 1103000011
where Number rlike '((00|11|22|33|44|55|66|77|88|99).*){3}'
Create a series of numbers from 0 to 9 with UNION ALL and cross join to the table.
Each of these numbers will be doubled and replaced in the column of the table with an empty string. The difference in length of each replacement will be summed and if it is greater than 6 this means that there exist at least 3 pairs:
select
n.number
from (
select 0 d union all select 1 d union all select 2 union all
select 3 union all select 4 union all select 5 union all
select 6 union all select 7 union all select 8 union all select 9
) s cross join numbers n
group by n.number
having sum(
length(n.number) - length(replace(n.number, repeat(d, 2), ''))
) >= 6
See the demo.
Results:
| number |
| ---------- |
| 0050000235 |
| 1103000011 |
| 1103220311 |
| 1122330505 |
| 5532003644 |
How about using regular expressions?
where number regexp '00.*00.*00'
Or slightly shorter:
where number regexp '(00.*){3}'
You can readily generalize this to any two numbers:
where number regexp '([0-9]{2}.*){3}'
If you want to ensure exactly six '0' (as opposed to more):
where number regexp '^[^0]*00[^0]*00[^0]*00[^0]*$'

Multiple select, subgroups

I have a little advise from SQL. I need to select a two groups (WHERE) in two columns. Some working 'like':
SELECT COUNT(WHERE Draw=1) as D1, COUNT(WHERE Draw=2) as D2 FROM SampleData
Exemple data table:
SampleData
--------------------
Id | Draw | Element
--------------------
1 | 1 | 13
2 | 1 | 15
3 | 1 | 22
4 | 1 | 36
5 | 1 | 45
6 | 2 | 11
7 | 2 | 15
8 | 2 | 22
And output like this:
Output:
--------
D1 | D2
--------
5 | 3
You can use CASE expression for this:
SELECT
COUNT(CASE WHEN Draw=1 THEN 1 END) as D1,
COUNT(CASE WHEN Draw=2 THEN 1 END) as D2
FROM SampleData
mysql also supports If() so you could also do something like the following. Just keep in mind this isn't portable to other RDBMS's but the CASE version is:
SELECT
SUM(IF(Draw=1, 1, 0)) as D1,
SUM(IF(Draw=2, 1, 0)) as D2
FROM SampleData;
Also... mysql supports math on Boolean expressions so you could get really terse here:
SELECT SUM(Draw=1) as D1, Sum(Draw=2) as D2 FROM SampleData;
Again though this is not portable to other RDBMSs like the CASE expression is.
Maybe something like this? (untested)
SELECT COUNT(*) as D1 FROM SampleData WHERE Draw = 1 UNION SELECT COUNT(*) as D2 FROM SampleData WHERE Draw = 2

SQL query taking "too" long - select with distinct and max

I have the scenario:
A table with POSITION and a value associated for each position, BUT I have always 4 values for the same position, so an example of my table is:
position | x| values
1 | x1 | 0
1 | x2 | 1
1 | x3 | 1.4
1 | x4 | 2
2 | x1 | 3
2 | x2 | 10
2 | x3 | 12.4
2 | x4 | 22
I need a query that returns me the MAX value for each unique position value. Now, I am querying it with:
SELECT DISTINCT (position) AS p, (SELECT MAX(values) AS v FROM MYTABLE WHERE position = p) FROM MYTABLE;
It took me 1651 rows in set (39.93 sec), and 1651 rows is just a test for this database (it probably should have more then 1651 rows.
What am I doing wrong ? are there any better way to get it in a faster way ?
Any help is appreciated.
Cheers.,
Use the GroupBy-Clause:
SELECT Position, MAX(VALUES) FROM TableName
GROUP BY Position
Also, have a look at the documentation (about groupby):
http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html
Try using the GROUP BY clause:
SELECT position AS p, MAX(values) AS v
FROM MYTABLE
GROUP BY p;
try this
SELECT position AS p, MAX(`values`) AS v FROM MYTABLE
GROUP BY position
DEMO HERE
OUTPUT:
P | V
1 | 2
2 | 22

MySQL count per item

I'm currently trying to make a mysql query that will count the number of zeros and ones per item, in the following way:
Table:
ID | PollID | Value
------------------------------------
1 | 1 | 1
2 | 1 | 1
3 | 2 | 0
4 | 2 | 1
5 | 1 | 0
And the result I want is:
Poll | one | zero
----------------------------------
1 | 2 | 1
2 | 1 | 1
Thanks for the help!
This is the shortest possible answer in MySQL because it supports boolean arithmetic.
SELECT PollID,
SUM(value = 1) AS `One`,
SUM(value = 0) AS `Zero`
FROM tableName
GROUP BY PollID
SQLFiddle Demo
select z.pollid,z.ones,s.zeros
from (select a.pollid,count(a.value) as ones from test a
where a.value=1
group by a.pollid) z
left join
(select b.pollid,count(b.value) as zeros from test b
where b.value=0 group by b.pollid) s
on z.pollid=s.pollid;
try this
select table.pollid,
Switch(table.value Like 1, 1)AS one,
Switch(table.value Like 0, 1)AS zero
from table
group by pollid