New to high level SQL stuff.
Want to make it so that a select statement will fill in values 7 times then move onto the next row.
EXAMPLE:
X | Y
A 1
A 2
....
A 7
B 1
B 2
....
This is some code that I have.
WHILE (*select that queries letters of unique value*) IS NOT NULL
BEGIN
INSERT INTO table1 (X,Y) *select that queries letters of unique value*,1
INSERT INTO table1 (X,Y) *select that queries letters of unique value*,2
....
INSERT INTO table1 (X,Y) *select that queries letters of unique value*,7
END
Would love some help. Thanks!
Here is another way too:
SELECT *
FROM
(
SELECT 'A' AS VAL1
UNION
SELECT 'B'
) A
CROSS JOIN
(
SELECT 1 AS VAL2
UNION
SELECT 2
UNION
SELECT 3
UNION
SELECT 4
UNION
SELECT 5
UNION
SELECT 6
UNION
SELECT 7
) B
ORDER BY A.VAL1
You can also do like:
CROSS JOIN
(
VALUES (1),(2),(3),(4),(5),(6),(7)
) B (VAL2)
ORDER BY A.VAL1
There is no need to use a loop, you can directly insert those values to your table like:
INSERT INTO YourTable (X, Y)
SELECT A.VAL1, B.VAL2
FROM...
Related
I want to find the minimum value present in 2 columns and max value present in 2 column
EX: A :2 3 4
B: 5 6 7
Ans should be 2 for min and 7 for max.
A and B are columns in same table.
min() inbuilt function doesn't exists.
I think the simplest way is apply:
select min(x.val), max(x.val)
from t cross apply
(select val
from (values (t.col1), (t.col2)) v(val)
) x;
The cross apply simply unpivots the values into a single column, before running the aggregation functions.
You could go with:
SELECT MIN(val), MAX(val) FROM (
SELECT a val FROM Table
UNION
SELECT b FROM Table
) d
Self-contained example.
declare #t table(a int, b int)
insert into #t values(2,5)
insert into #t values(3,6)
insert into #t values(4,7)
select min(a) as a,max(b) as b from #t
--if for some reason min() and max() are 'not available' (???)
select
(select top 1 a from #t order by a asc) as a
,(select top 1 b from #t order by a desc) as b
If there is indexing which is appropriate, it might be more efficient to do the MIN/MAX independently first on columns A and B since it would hopefully use some seeks into appropriate indexes on those columns:
SELECT MIN(mn), MAX(mx)
FROM (
SELECT MIN(A) AS mn, MAX(A) AS mx FROM tbl
UNION ALL
SELECT MIN(B) AS mn, MAX(B) AS mx FROM tbl
) x;
you can use Max and Min function to determine the max n min values for that column.
Select Min(A),Max(B) from Table
I have a table that gets rewritten each night. I have two columns that need to be populated with a random number from a set list of values. Angle column needs to be populated with 15,30,45,60,90 and Distance needs to populated with 9,15,21. The insert statements may process up to 700 records.
I have tried creating a temp table (#MyRandomVal1) with
select 15 union
select 30 union
select 45 etc...
Then use (select top 1 val from #MyRandomVal1 order by newid()). This populates the column with the same random number for all rows. It seems that I might need to loop through the inserted rows so it runs (select top 1 val from #MyRandomVal1 order by newid()) for each row, however in my research I have read that Loops are not recommended. Is there another method for populating 700+ rows with a random sampling from a set list during an insert?
Below is my existing code (for angle only). SQL Server 2012.
DECLARE #MyRandomVal1 Table (
id int identity (1,1),
val int not null)
INSERT INTO #MyRandomVal1 (val)
SELECT 15
union
SELECT 30
union
SELECT 45
union
SELECT 60
union
SELECT 90
INSERT INTO MyTable (AUTO_KEY,E3_KEY,EMPID,ENAME,COLOR,ANGLE)
SELECT dbo.getautokey(),dbo.GetAutoKey(),[EMPID],[ENAME],abs(checksum(NewId()) % 256),(select top 1 val from #MyRandomVal1 order by newid())
FROM MyTable2 WHERE [JOBLEVEL]='SVP'
Thanks.
One way to do it is with a cte. Join your #MyRandomVal1 to MyTable2 on true. Add a row number that is ordered by newid(). Then get all the rownumber 1's. You'll want to check the logic in the PARTITION BY. I didn't know if there was a column that was unique. If not you may have to partition by all columns since we are joining each row to every row in the random value table.
DECLARE #MyRandomVal1 Table (
id int identity (1,1),
val int not null)
INSERT INTO #MyRandomVal1 (val)
SELECT 15
union
SELECT 30
union
SELECT 45
union
SELECT 60
union
SELECT 90
;WITH cte AS (
SELECT
dbo.getautokey() AS AUTO_KEY
, dbo.GetAutoKey() AS E3_KEY
, [EMPID]
, [ENAME]
, ABS(checksum(NewId()) % 256) AS COLOR
, a.val
, ROW_NUMBER() OVER (PARTITION BY empid ORDER BY NEWID()) AS rn
FROM MyTable2
JOIN #MyRandomVal1 a ON 1 = 1
WHERE [JOBLEVEL]='SVP')
INSERT INTO MyTable (AUTO_KEY, E3_KEY, EMPID,ENAME, COLOR, ANGLE)
SELECT * FROM cte
WHERE rn = 1
Here's a simple DEMO since we don't have example data.
I have 4 parts, each part is made out of 2 select statement. I need the 1st 2 part to be UNION'd with the 2nd part. Each part contains its own ORDER BY. I need the results to appear 1st part first and followed by the 2nd part. Only each part is sorted but not the overall result set.
(select col1,col2,col3,col4,col5 from tableA where col1 = 'x'
UNION ALL
select col1,col2,col3,col4,col5 from tableB where col1 = 'x'
ORDER BY Col3) --1st part ends here
--now I need to UNION the 2nd part
UNION ALL
(select col1,col2,col3,col4,col5 from tableA where col1 <> 'x'
UNION ALL
select col1,col2,col3,col4,col5 from tableB where col1 <> 'x'
ORDER BY Col3) --2nd part ends here
I tried wrapping each select in the SELECT * FROM (... but I'm having issues with ORDER BY. Just can't seem to get the syntax right.
Just add a column for this purpose:
select col1,col2,col3,col4,col5, ord = 1 from tableA where col1 = 'x'
UNION ALL
select col1,col2,col3,col4,col5, ord = 1 from tableB where col1 = 'x'
UNION ALL
select col1,col2,col3,col4,col5, ord = 2 from tableA where col1 <> 'x'
UNION ALL
select col1,col2,col3,col4,col5, ord = 2 from tableB where col1 <> 'x'
ORDER BY ord, Col3
The ORDER BY applies over the whole result set, after the UNION. See Example C: https://msdn.microsoft.com/en-us/library/ms180026%28v=sql.110%29.aspx
You can't have the ORDER BY in the queries within the UNION.
I have a source table with id and count.
id count
a 5
b 2
c 31
I need to populate a destination table with each integer up to the count for each id.
id value
a 1
a 2
a 3
a 4
a 5
b 1
b 2
c 1
c 2
etc...
My current solution is like so:
INSERT INTO destination (id,value)
source.id
sequence.number
FROM
(VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9)) AS sequence(number)
INNER JOIN
source ON sequence.number <= source.count
This solution has an upper limit and is plain lame. Is there anyway to replace the sequence with a set of all integers? Or another solution that does not use looping.
this should work:
WITH r AS (
SELECT id, count, 1 AS n FROM SourceTable
UNION ALL
SELECT id, count, n+1 FROM r WHERE n<count
)
SELECT id,n FROM r
order by id,n
OPTION (MAXRECURSION 0)
Unfortunately, there is not set of all integers in SQL Server. However, using a little trickery, you can easily generate such a set:
select N from (
select ROW_NUMBER() OVER (ORDER BY t1.object_id) AS N
from sys.all_objects t1, sys.all_objects t2
) AS numbers
where N between 1 and 1000000
will generate a set of all numbers from 1 through 1000000. If you need more than a few million numbers, add sys.all_objects to the cross join a third time.
You can find many examples in this page:
DECLARE #table TABLE (ID VARCHAR(1), counter INT)
INSERT INTO #table SELECT 'a', 5
INSERT INTO #table SELECT 'b', 3
INSERT INTO #table SELECT 'c', 31
;WITH cte (ID, counter) AS (
SELECT id, 1
FROM #table
UNION ALL
SELECT c.id, c.counter +1
FROM cte AS c
INNER JOIN #table AS t
ON t.id = c.id
WHERE c.counter + 1 <= t.counter
)
SELECT *
FROM cte
ORDER BY ID, Counter
I need to select the rows with the minimum distance by grouping on the OrganisationID. Here is my data in a single table:
ID OrganisationID Distance
0 10 100
1 10 200
3 10 50
4 20 80
5 20 300
This is the result I want:
ID OrganisationID Distance
3 10 50
4 20 80
This will accomplish that:
SELECT t1.*
FROM yourTable t1
LEFT JOIN yourTable t2
ON (t1.OrganisationID = t2.OrganisationID AND t1.Distance > t2.Distance)
WHERE t2.OrganisationID IS NULL;
sqlfiddle demo
Note that if there are multiple rows with the lowest distance duplicate, this returns them both
EDIT:
If, as you say in the comments, only want one column and the MIN distance you can do it easily with MIN and GROUP BY:
SELECT city, MIN(distance)
FROM table2
GROUP BY city;
sqlfiddle demo
p.s. i saw your previous question that you deleted, and was answering it with a different thing than this (was going to tell you that since you had the organisationID in the WHERE clause, you could just do: SELECT TOP 1 ... order by Distance DESC), but if you need more it for more than one organisationID, this is something that can get you there)
This is the solution:
SELECT ID ,D.*
FROM <TABLE> INNER JOIN( SELECT OrganisationID 'OR',MIN(Distance) DI
FROM <TABLE>
GROUP BY OrganisationID) D
ON D.DI=<TABLE>.Distance
Test :
CREATE TABLE #T
(
ID INT,
OrganisationID INT,
Distance INT
)
INSERT INTO #T
SELECT 0,10,100
UNION ALL
SELECT 1,10,200
UNION ALL
SELECT 3,10,50
UNION ALL
SELECT 4,20,80
UNION ALL
SELECT 5,20,300
SELECT ID ,D.*
FROM #T INNER JOIN( SELECT OrganisationID 'OR',MIN(Distance) DI
FROM #T
GROUP BY OrganisationID) D
ON D.DI=#T.Distance
DROP TABLE #T