SELECT ID FROM TABLE WHERE ID BETWEEN 1 AND 5
The result of the query above will be: 1,2,3,4,5
If only id 1 and id 2 who are exist in the table, then it will loop (1,2) only.
It means, if the id is between 1 AND 5, the id of 3,4,5 doesn't exist.
the id of 3,4,5 is what I want to select. How to do this?
Thanks in advance.
Try this:
select * from
(
select 1 as val
union all
select 2
union all
select 3
union all
select 4
union all
select 5
)t
left join TableName tn on t.val = tn.id
where tn.id is null
With tally table:
select * from (
select (3 + th*1000+h*100+t*10+u+1) x from
(select 0 th union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9) A,
(select 0 h union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9) B,
(select 0 t union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9) C,
(select 0 u union select 1 union select 2 union select 3 union select 4 union
select 5 union select 6 union select 7 union select 8 union select 9) D)
tn
left join t on tn.x = t.id
where tn.x between 3 and 10
and t.id is null
Notice in formula (3 + th*1000+h*100+t*10+u+1) and where clause 3 is srart, 10 is end. Change on variables.
Here is fiddle: http://sqlfiddle.com/#!9/2f53f/2
Related
I often need to generate a range of IDs using a sequential number.
I use code like this ...
SELECT
numbers.value
FROM
(
SELECT
(((c3.d * 10) + c2.d) * 10) + c1.d value
FROM
(SELECT 0 d UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) c1,
(SELECT 0 d UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) c2,
(SELECT 0 d UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) c3
) numbers
WHERE
numbers.value BETWEEN 192 AND 264
This is then used in the context required.
Is there a less verbose way to do this?
If I was on MSSQL, then a CTE would be ideal. A function is also a possibility, but not exactly sure how to achieve that.
EDIT: I'm using mysql 5, so no WITH unfortunately.
I am bit new to MySQL. I am trying to create a mysql function that will produce and output a query with a single column with values from 1 to that given number.
Start of the function looks like,
create function get_NumberSequence (n)
Suppose I call the function as,
select get_NumberSequence(5);
I should get the output like below.
Sequence
--------
1
2
3
4
5
I tried an approach to combine and store queries like,
#num:=(select 1 as Sequence)
#num:=#num union (select 2 as Sequence)
This didn't work for me.
This is for case that your input number l_input_number < 10^4 (10000).
You could change your query with larger input number
SELECT #row := #row + 1 as sequence
FROM
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t,
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t2,
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t3,
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t4,
(SELECT #row:=0) t_init
LIMIT 17; --LIMIT l_input_number;
And use IF ELSE STATEMENT for each query of input number range for better performance
IF l_input_number < 1000
THEN --only use query up to t3
ELSEIF l_input_number < 10000
THEN --use query up to t4
ELSEIF l_input_number < 100000
THEN --use query up to t5
--etc........
END IF;
How can i join this two selects without using a subquery in the from clause?
SELECT 0 a UNION SELECT 1 a UNION SELECT 2 UNION SELECT 3
UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7
UNION SELECT 8 UNION SELECT 9;
SELECT 0 b UNION SELECT 10 UNION SELECT 20
UNION SELECT 30 UNION SELECT 40 UNION SELECT 50 UNION SELECT 60
UNION SELECT 70 UNION SELECT 80 UNION SELECT 90;
The result should be 100 Rows:
every a(0,1,2,3,4,5,6,7,8,9) joined with every b(0,10,20,30,40,50,60,70,80,90)
I need that, because i can´t create a view, if there are subqueries in the from clause...
Thank you!
Use CROSS JOIN
SELECT
*
FROM
( SELECT 0 a UNION SELECT 1 a UNION SELECT 2 UNION SELECT 3
UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7
UNION SELECT 8 UNION SELECT 9 ) AS A
CROSS JOIN
(
SELECT 0 b UNION SELECT 10 UNION SELECT 20
UNION SELECT 30 UNION SELECT 40 UNION SELECT 50 UNION SELECT 60
UNION SELECT 70 UNION SELECT 80 UNION SELECT 90
) AS B
Note:
If table A has n rows and table B has m rows then
A CROSS B will have m * n rows
I have this MySQL table :
create table example (
My_Id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
My_Integer INT UNSIGNED DEFAULT 0
) ENGINE=InnoDB
Suppose this table to be populated like that :
SELECT * FROM `example`
My_Id My_Integer
1 10
2 1
3 3
4 152
5 16
6 481
7 128
My goal is to retrieve, from an user input, which integer is not in my table 'example'.
For example, if the user enter 1, 3, 10, the result should be empty.
If the user enter 1, 2, 3, 10, the result should be "2".
I can't find a way to do that, other than to do one MySQL request per integer in order to know if the number is in the table 'example'.
Do someone know a way ?
Select numberToMatch
from example as a
right outer join (
select 1 as numberToMatch union all
select 2 union all
select 3 union all
select 10
) as b
on b.numberToMatch = a.My_Integer
where a.My_Integer is null
Using right outer join and select those null record in the left table.
You could genereate tally table and use OUTER JOIN:
SELECT t.n
FROM (
SELECT a.N + b.N * 10 + c.N * 100 + 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
,(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) c
) t
LEFT JOIN example e
ON t.n = e.My_Integer
WHERE t.n IN (1,2,3,10) -- here goes numbers
AND e.My_Integer IS NULL;
LiveDemo
Output:
╔═══╗
║ n ║
╠═══╣
║ 2 ║
╚═══╝
It will work in range 1-999. You could expand it if needed.
Another way is to use UNION ALL:
SELECT s.col
FROM (SELECT 1 AS col
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 10) AS s
LEFT JOIN example e
ON s.col = e.My_Integer
WHERE e.My_Integer IS NULL;
LiveDemo2
Mainly, I would like to insert a row in table 1 multiple times, based on an integer value in a column of table 2.
My situation
Table 2 contains a column 'SKU' and 'stock', and I would like to insert the 'SKU' and a timestamp into table 1. I want this row duplicated for 'stock'-value times in table 1.
I currently have the following query:
DECLARE #Count int = 1
WHILE #Count <= ....
BEGIN
INSERT INTO table1 (table1.SKU, table1.timestamp_in)
SELECT table2.SKU, "some timestamp" FROM table2
SET ...
END
I am not sure if this is the correct approach. I would like to run this loop for 'table2.stock' times.
My question is: Is this possible with just a SQL query, or should it be a better practice to build some (in my case) java code for this?
You don't need a procedure or anything like that. All you need is a table containing just numbers. I'm creating this table on the fly with this in this example:
SELECT aa.a + 10*bb.b + 100*cc.c AS numbers FROM (
SELECT 0 a 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) aa
, (SELECT 0 b 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) bb
, (SELECT 0 c 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) cc;
This creates the numbers 0 till 999.
Now you join your table2 with this numbers table in the range of stock. Your final query looks like this:
INSERT INTO table1 (table1.SKU, table1.timestamp_in)
SELECT table2.SKU, "some timestamp" FROM table2
INNER JOIN (
SELECT aa.a + 10*bb.b + 100*cc.c AS n FROM (
SELECT 0 a 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) aa
, (SELECT 0 b 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) bb
, (SELECT 0 c 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) cc
) numbers ON numbers.n BETWEEN 0 AND table2.stock /*assuming you have no negative stock*/
Just make sure, that the numbers table contains more numbers than the highest value in the stock column.