I am looking for a way to populate values in row in mysql
for example if i execute query
select 1,2,3,4
it gives response
+---+---+---+---+
| 1 | 2 | 3 | 4 |
+---+---+---+---+
| 1 | 2 | 3 | 4 |
+---+---+---+---+
that is in row
is there a possible way to produce this data in column
like
1
2
3
4
With the introduction of Recursive with clause in MySQL version 8.0 or higher, We now have a row generator in MySQL -
WITH RECURSIVE cte_count (n)
AS (
SELECT 1
UNION ALL
SELECT n + 1
FROM cte_count
WHERE n < 100
)
SELECT n
FROM cte_count;
Before version 8.0 MySQL doesn't have any inbuilt row_generator functionality.
If you want values in a column, you can use:
select 1 as n union all
select 2 as n union all
select 3 as n union all
select 4 as n
This construct is often used in derived tables (or more recently in CTEs).
If you just need a set number of values, then an existing table (that is big enough) can be used:
select (#rn := #rn + 1) as n
from t cross join
(select #rn := 0) params
limit 4;
Related
I know there is sql query to print count from 1 to 10 as below:
select rownum from dual where rownum<=10;
In the same way i am trying in the mysql but it is throwing error "Unknown column rownum in field list". So, It would be great if anyone provide me the mysql query to perform the same operation. Thanks in advance.
In MySQL 8+ you can use a recursive CTE to do this:
WITH RECURSIVE cte AS (
SELECT 1 AS n
UNION ALL
SELECT n + 1 FROM cte WHERE n < 10
)
SELECT n FROM cte
Output:
n
1
2
3
4
5
6
7
8
9
10
Demo on dbfiddle
There is no straightforward way to do this in MySQL.
MySQL does not fully support the DUAL table. It can be used as a placeholder table in certain queries which do not require a table, but it does not have the same behavior as the DUAL table in other database servers -- it will only ever return one row, even if more rows are requested:
mysql> SELECT ROW_NUMBER() OVER() FROM DUAL LIMIT 10;
+---------------------+
| row_number() over() |
+---------------------+
| 1 |
+---------------------+
mysql> SELECT ROW_NUMBER() OVER() FROM DUAL WHERE ROW_NUMBER() OVER() < 10;
ERROR 3593 (HY000): You cannot use the window function 'row_number' in this context.'
(Yes, there's really a stray apostrophe at the end of that error message.)
There is one really dumb way of creating a sequence:
mysql> SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5;
+---+
| 1 |
+---+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+---+
5 rows in set (0.00 sec)
Obviously, this gets unwieldy for large sequences, but it's about the best you'll get in stock MySQL. (Some of the forks, like MariaDB, have some features which can be used for this.)
Using the table function (the method for creating a temporary table only for the current query): like numbers function which will print 1 to 10:
SELECT * FROM numbers(1, 10);
By using below query you can get 1 to 10.
Sequence of 10 numbers
select * from (select 1 x union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9 union select 10) A
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=1f8b71c1fef4b8e0350f2b28eb15c3be
I have query like this :
SELECT * FROM (
SELECT * FROM (
SELECT 1 AS a,1 AS b
UNION
SELECT 2 AS a,1 AS b
UNION
SELECT 3 AS a,2 AS b
UNION
SELECT 3 AS a,1 AS b
) b ORDER BY b.b DESC
) c
It's show different result on different machine,
On Machine A :
A | B
--------
3 | 2
1 | 1
2 | 1
3 | 1
On Machine B :
A | B
--------
1 | 1
2 | 1
3 | 2
3 | 1
I'm expecting all machine will get result like machine A. How can it happen ? Is there any setting on mysql server to make all machine to get result like machine A ?
The inner ORDER BY is meaningless as you have written it, and only an ORDER BY on the outer query will be honored. In addition, I don't even see the point of the subquery, so just use this:
SELECT * FROM (
SELECT 1 AS a, 1 AS b
UNION
SELECT 2, 1
UNION
SELECT 3, 2
UNION
SELECT 3, 1
) t
ORDER BY b DESC;
SQL tables are modeled after unordered sets of records, and generally have no internal order. The inner ORDER BY you were doing does not "stick," and MySQL is free to return any order it wants in the outer query since you did not use ORDER BY there.
I found some answers for this question on stack but non of them worked. I can say I understand mysql fairly well but not well enough to make this work.
Here it goes, I have table that looks like this:
id | Name | Sales
---|------|------
0 | Tim | 9
1 | Jim | 5
2 | Joe | 3
3 | Ryan | 6
4 | Phil | 7
5 | James| 1
Notice the ID-s may not be in order in the future, so it may be 1, 4, 10, 11, 12 etc, still unique but not incremental like +1 due to the user deleting some stuff and adding other stuff.
Now I want to select and ID (for example 3) and get the two rows above it and bellow it. If the ID is 0 then select 4 rows bellow 0 (so always 5 rows).
UPDATE oh my, I am so dumb. I don`t need to select two rows up and down by the ID, I need to select them by the sales instead. But still need the rows up and down from a specific ID bud depending from the sales. Sorry everyone. I still need help though.
If you want to do this by id order, it is a bit tricky, because of the condition of always getting 4 rows. Here is an approach. The idea is to select up to 4 before the id and up to 4 after the id, along with the id itself. Then, using MySQL variables, enumerate the rows.
The final select chooses enumeration values of 0, 1, and 2. This should produce 5 rows exactly:
select t.*
from ((select t.*, #rn1 := #rn1 + 1 as rn
from t cross join
(select #rn1 := 0) const
where id < MYID
order by id desc
limit 4
) union all
(select t.*, #rn2 := #rn2 + 1 as rn
from t cross join
(select #rn2 := 0) const
where id > MYID
order by id
limit 4
) union all
(select t.*, 0 as rn
from t
where id = MYID
)
) t
where rn <= 2;
Let's say you want to pull out 5 ids, that are close to id 12. You could calculate the distance to the desired id by subtraction and use the absolute value for ordering.
SELECT ABS(12-10) => 2
SELECT ABS(12-11) => 1
SELECT ABS(12-12) => 0
SELECT ABS(12-13) => 1
SELECT ABS(12-14) => 2
E.g. a query to pull 5 rows with ordering ids by distance to the desired id 12, could look like:
SELECT * FROM `test_table` ORDER BY ABS(12-CAST(`id` AS SIGNED)) LIMIT 5
NOTE: This technique will become slower according to amount of ids, as all ids will be sorted. Tested it with 100 000 rows at debian, Intel Xeon 2.4Ghz, 4gb ram, speed for the query was ~0.11 sec.
To keep performance up on larger tables, use a WHERE clause to limit the number of rows to be sorted:
WHERE id BETWEEN (desired id - 1000) AND (desired id + 1000)
Please, read the documentation:
SELECT
UNION
Here is an example:
(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);
Change it to your needs ;)
This question already has answers here:
MySQL: Split comma separated list into multiple rows
(4 answers)
Closed 9 years ago.
I have a column with a variable number of comma seperated values:
somethingA,somethingB,somethingC
somethingElseA, somethingElseB
And I want the result to take each value, and create a row:
somethingA
somethingB
somethingC
somethingElseA
somethingElseB
How can I do this in SQL (MySQL)?
(I've tried googling "implode" and "lateral view", but those don't seem to turn up related questions. All the related SO questions are trying to do much more complicated things)
You can do it with pure SQL like this
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(t.values, ',', n.n), ',', -1) value
FROM table1 t CROSS JOIN
(
SELECT a.N + b.N * 10 + 1 n
FROM
(SELECT 0 AS N UNION ALL SELECT 1 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) a
,(SELECT 0 AS N UNION ALL SELECT 1 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) b
ORDER BY n
) n
WHERE n.n <= 1 + (LENGTH(t.values) - LENGTH(REPLACE(t.values, ',', '')))
ORDER BY value
Note: The trick is to leverage tally(numbers) table and a very handy in this case MySQL function SUBSTRING_INDEX(). If you do a lot of such queries (splitting) then you might consider to populate and use a persisted tally table instead of generating it on fly with a subquery like in this example. The subquery in this example generates a sequence of numbers from 1 to 100 effectively allowing you split up to 100 delimited values per row in source table. If you need more or less you can easily adjust it.
Output:
| VALUE |
|----------------|
| somethingA |
| somethingB |
| somethingC |
| somethingElseA |
| somethingElseB |
Here is SQLFiddle demo
This is how the query might look with a persisted tally table
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(t.values, ',', n.n), ',', -1) value
FROM table1 t CROSS JOIN tally n
WHERE n.n <= 1 + (LENGTH(t.values) - LENGTH(REPLACE(t.values, ',', '')))
ORDER BY value
Here is SQLFiddle demo
Hi there m trying to calculate the row count for same value,
id,value
1 | a
2 | b
3 | c
4 | d
5 | e
and my query is
select value, count(*) as Count from mytable where id in('4','2','4','1','4') group by value having count(*) > 1
for which my expected output will be,
value,Count
d | 3
b | 1
a | 1
Thanks, any help will be appreciated
Try that:
SELECT value, count(value) AS Count
FROM mytable m
WHERE value = m.value
GROUP BY value
SELECT t.id, t.value, COUNT(t.id)
FROM
test t
JOIN
( SELECT 1 AS id
UNION ALL SELECT 3
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 1
UNION ALL SELECT 1 ) AS tmp
ON t.id = tmp.id
GROUP BY t.id
Sample on sqlfiddle.com
See also: Force MySQL to return duplicates from WHERE IN clause without using JOIN/UNION?
Of course, your IN parameter will be dynamic, and thus you will have to generate the corresponding SQL statement for the tmp table.
That's the SQL-only way to do it. Another possibility is to have the query like you have it in your question and afterwards programmatically associate the rows to the count passed to the IN parameter.