I use this procedure to select records with paging :
ALTER PROCEDURE [PorSun].[soalPagingByIdGroupIdUser] (
#IdGroup ,
#pageNo int,
#pageSize int)
AS
DECLARE #start int, #end int
SET #start = #pageSize*(#pageNo-1)+1
SET #end= #start+#pageSIze-1
;with Records as
(
SELECT
PorSun.soal.Id, PorSun.soal.IdUser, PorSun.soal.VisitCount
, ROW_NUMBER() over(order by PorSun.soal.Id) as RN
FROM PorSun.soal
WHERE (PorSun.soal.IdGroup=#IdGroup)
)
SELECT Records.Id, Records.IdUser, Records.VisitCount
FROM Records
WHERE RN between #start and #end and (Records.IdGroup=#IdGroup)
ORDER BY Records.Id desc
UPDATE [PorSun].[Soal]
SET [VisitCount] = [VisitCount]+1
WHERE Id IN (SELECT Id FROM Records)
There is no syntax error, but on execute error.
How is it possible?
You can use a table variable instead of a CTE:
DECLARE #Records TABLE
(
Id int,
IdUser int,
VisitCount int,
RN int
)
INSERT INTO #Records
SELECT
PorSun.soal.Id,
PorSun.soal.IdUser,
PorSun.soal.VisitCount,
ROW_NUMBER() over(order by PorSun.soal.Id) as RN
FROM PorSun.soal
WHERE (PorSun.soal.IdGroup=#IdGroup)
SELECT Id, IdUser, VisitCount
FROM #Records
WHERE RN between #start and #end and (IdGroup=#IdGroup)
ORDER BY Id desc
UPDATE [PorSun].[Soal]
SET [VisitCount] = [VisitCount]+1
WHERE Id IN (SELECT Id FROM #Records)
Related
normally it works fine (it recalculates time to time production based on daily meter readings , the problem starts when other apps are inserting data into [dbo].[MeterReading] ( at least I belive this is the source of deadlocks), what would you reccomend to avoid exceptions ?
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
declare #ResultVar float;
DECLARE #Val1 TABLE
(
RowID INT IDENTITY ( 1 , 1 ),
InputId int,
TimeStampUtc1 smalldatetime,
Val1 float
);
DECLARE #Val2 TABLE
(
RowID INT IDENTITY ( 1 , 1 ),
InputId int,
TimeStampUtc2 smalldatetime,
Val2 float
);
WITH CTE
AS
(
SELECT [Val],m.InverterInputId, m.[TimeStampUtc]
,ROW_NUMBER() OVER(PARTITION BY m.InverterInputId ORDER BY m.[TimeStampUtc] DESC) AS RN
FROM [dbo].[MeterReading] AS m
inner join InverterInput AS ii on m.InverterInputId = ii.InverterInputId
inner join Inverter AS i on ii.InverterId = i.InverterId
where ii.InputName = 'TotalYield' and i.PlantId = #plantId and m.[TimeStampUtc] >= #from and m.[TimeStampUtc] <= #to
)
INSERT INTO #Val1 (Val1,InputId,TimeStampUtc1 ) Select [Val],[InverterInputId],[TimeStampUtc] FROM CTE WHERE RN = 1;
WITH CTE
AS
(
SELECT [Val],m.InverterInputId, m.[TimeStampUtc]
,ROW_NUMBER() OVER(PARTITION BY m.InverterInputId ORDER BY m.[TimeStampUtc] ASC) AS RN
FROM [dbo].[MeterReading] AS m
inner join InverterInput AS ii on m.InverterInputId = ii.InverterInputId
inner join Inverter AS i on ii.InverterId = i.InverterId
where ii.InputName = 'TotalYield' and i.PlantId = #plantId and m.[TimeStampUtc] >= #from and m.[TimeStampUtc] <= #to
)
INSERT INTO #Val2 (Val2,InputId,TimeStampUtc2) Select [Val],[InverterInputId],[TimeStampUtc] FROM CTE WHERE RN = 1;
--select Val1 , Val2, Val1-Val2 as Result, [#Val1].InputId,[#Val1].TimeStampUtc1,[#Val2].TimeStampUtc2 from #Val1
select Sum(Val1-Val2) as Result from #Val1
inner join #Val2 on [#Val1].InputId = [#Val2].InputId
END
I want query field with different alias in stored procedure
select COUNT(EmpCode) as CountEmp+#para
result shoud be
CountEmp1
45
CountEmp2
54
CountEmp1
76
Query loop in c# code:
select COUNT(EmpCode) where something = #something as CountEmp+#para
Approach without dynamic SQL:
--I create temp table for demonstration
DECLARE #some_table TABLE (
Something int,
EmpCode INT
)
INSERT INTO #some_table (Something, EmpCode)
VALUES (1, 10),(1, 22),(1, 12),(2, 12),(2, 30),(3, 65),(3, 15),(3, 11),(3, 5)
--Declare parameter we want to search
DECLARE #param int = 1
--Query
--In cte we select what we need based on parameter
;WITH cte AS (
SELECT 'CountEmp'+CAST(#param as nvarchar(10)) as SomeThing,
CAST(COUNT(EmpCode) as nvarchar(10)) as EmpCodeCount,
ROW_NUMBER() OVER (ORDER BY SomeThing ) as rn
FROM #some_table
WHERE SomeThing = #param
GROUP BY SomeThing
)
--And here comes UNION
SELECT SomeThing as Result
FROM (
SELECT SomeThing,rn
FROM cte
UNION ALL
SELECT EmpCodeCount ,rn
FROM cte
) as t
ORDER BY rn, SomeThing DESC
Output:
Result
------------------
CountEmp1
3
(2 row(s) affected)
Please try to make use of below code. Its working fine with SQL Server 2012.
IF OBJECT_ID ('temp..#Mytable') IS NOT NULL
CREATE TABLE #Mytable (ID INT IDENTITY (1,1),EmpCode INT)
DECLARE #max int ,#count int
SET #max =0;
DECLARE #str varchar(10)
INSERT #Mytable
(EmpCode)
VALUES
(10),
(45),
(35),
(63),
(56),
(65)
SET #count = (SELECT COUNT (ID) FROM #Mytable )
WHILE #count > #max
BEGIN
SET #max = #max+1
SET #str = CONVERT(varchar(10),#max)
EXEC('SELECT EmpCode AS Empcode'+#str+ ' FROM #Mytable WHERE ID = '+#str)
END
(The database is Postgres )
Let's say I have a table races with columns (user_name , race_time , race_speed , race_no).
Each users can have multiple races . I want to get data for each month and show for each month how many races are played in that month. But I also want to show which user played the most and which played has the maximum speed.
select
extract ( month from race_time) as month,
extract ( year from race_time) as year,
count(race_no) as total_races
from races r
group by year,month
order by year desc,month desc
The above query gives me each month and the total races but how can I find for each month which user played the most (that'd be one user)?
I hope someone could help me with this.
SQL Fiddle
with r as (
select
to_char(race_time, 'YYYY-MM') as month,
user_name,
count(*) as n_races,
max(race_speed) as max_speed
from races
group by 1, 2
), total_races as (
select sum(n_races) as total_races, month
from r
group by month
)
select *
from (
select distinct on (month)
month, user_name as user_most_races, n_races as most_races
from r
order by 1, 3 desc
) s
inner join (
select distinct on (month)
month, user_name as user_max_speed, max_speed
from r
order by 1, 3 desc
) q using (month)
inner join
total_races using(month)
order by month
SELECT COUNT(DISTINCT user_name), user_name, EXTRACT(month FROM race_time) AS month, EXTRACT(year FROM race_time) AS year
FROM races r
GROUP BY user_name, year, month
ORDER BY year desc, month desc
Try it!
USE [DATABASE_NAME]
GO
--this is calculating the which user played the most
CREATE FUNCTION [dbo].[GetHighestPlayedRaceUserByYearMonth]
(
-- Add the parameters for the function here
#Year INT, #Month INT
)
RETURNS NVARCHAR(50)
AS
BEGIN
-- Declare the return variable here
DECLARE #UserName NVARCHAR(50)
-- Add the T-SQL statements to compute the return value here
DECLARE #TempTbl TABLE(Played INT,UserName NVARCHAR(50))
INSERT INTO #TempTbl(Played,UserName)
SELECT
COUNT(race_no) AS Played,
[user_name] AS UserName
FROM Table_1
WHERE
YEAR(race_time)=#Year and
MONTH(race_time)=#Month
GROUP BY
MONTH(race_time),
YEAR(race_time),
[user_name]
ORDER BY
YEAR(race_time) DESC,
MONTH(race_time) DESC,
COUNT(race_no) DESC
DECLARE #MaxPlayed INT
SET #MaxPlayed=(SELECT TOP 1 Played FROM #TempTbl ORDER BY Played DESC)
DECLARE #TempTbl2 TABLE(ID INT IDENTITY(1,1) NOT NULL,UserName NVARCHAR(50))
INSERT INTO #TempTbl2
SELECT UserName FROM #TempTbl WHERE Played=#MaxPlayed
DECLARE #ROWCOUNT INT
SET #ROWCOUNT=1
SET #UserName=''
WHILE (SELECT COUNT(*) FROM #TempTbl2)>=#ROWCOUNT
BEGIN
IF (SELECT COUNT(*) FROM #TempTbl2)=#ROWCOUNT
BEGIN
SET #UserName= #UserName+(SELECT UserName FROM #TempTbl2 WHERE ID=#ROWCOUNT)
END
ELSE
BEGIN
SET #UserName= #UserName+(SELECT UserName FROM #TempTbl2 WHERE ID=#ROWCOUNT)+','
END
SET #ROWCOUNT=#ROWCOUNT+1
END
-- Return the result of the function
RETURN #UserName
END
GO
--this is calculating which user played with the maximum speed
CREATE FUNCTION [dbo].[GetMaxRaceSpeedUserByYearMonth]
(
-- Add the parameters for the function here
#Year INT, #Month INT
)
RETURNS NVARCHAR(50)
AS
BEGIN
-- Declare the return variable here
DECLARE #UserName NVARCHAR(50)
-- Add the T-SQL statements to compute the return value here
DECLARE #TempTbl TABLE(MaxRaceSpeed INT,UserName NVARCHAR(50))
INSERT INTO #TempTbl(MaxRaceSpeed,UserName)
SELECT
MAX(race_speed) AS MaxRaceSpeed,
[user_name] AS UserName
FROM Table_1
WHERE
YEAR(race_time)=#Year and
MONTH(race_time)=#Month
GROUP BY
MONTH(race_time),
YEAR(race_time),
[user_name]
ORDER BY
YEAR(race_time) DESC,
MONTH(race_time) DESC,
COUNT(race_no) DESC
DECLARE #MaxRaceSpeed INT
SET #MaxRaceSpeed=(SELECT TOP 1 MaxRaceSpeed FROM #TempTbl ORDER BY MaxRaceSpeed DESC)
DECLARE #TempTbl2 TABLE(ID INT IDENTITY(1,1) NOT NULL,UserName NVARCHAR(50))
INSERT INTO #TempTbl2
SELECT UserName FROM #TempTbl WHERE MaxRaceSpeed=#MaxRaceSpeed
DECLARE #ROWCOUNT INT
SET #ROWCOUNT=1
SET #UserName=''
WHILE (SELECT COUNT(*) FROM #TempTbl2)>=#ROWCOUNT
BEGIN
IF (SELECT COUNT(*) FROM #TempTbl2)=#ROWCOUNT
BEGIN
SET #UserName= #UserName+(SELECT UserName FROM #TempTbl2 WHERE ID=#ROWCOUNT)
END
ELSE
BEGIN
SET #UserName= #UserName+(SELECT UserName FROM #TempTbl2 WHERE ID=#ROWCOUNT)+','
END
SET #ROWCOUNT=#ROWCOUNT+1
END
-- Return the result of the function
RETURN #UserName
END
GO
--Select Query
SELECT
MONTH(race_time) AS [Month],
YEAR(race_time) AS [Year],
COUNT(race_no) AS RacePlayed,
dbo.GetHighestPlayedRaceUserByYearMonth(YEAR(race_time),MONTH(race_time)) AS MaximunPlayedUser,
dbo.GetMaxRaceSpeedUserByYearMonth(YEAR(race_time),MONTH(race_time)) AS MaximunSpeedUser
FROM TABLE_NAME
GROUP BY MONTH(race_time),YEAR(race_time)
ORDER BY YEAR(race_time) DESC,MONTH(race_time) DESC
how to determine which row number in my database will the selection query start to select and the Limit of the selection ,as I want to select piece of data which is located in the middle of my database table
I may use between #indexOfSelection , #limitOfSelection or something like that ,but I don't know how !
CREATE PROCEDURE ordered_articles
#LowerBound int,
#UpperBound int
AS
select * from orderedData where articleid between LowerBound and UpperBound ;
with orderedData
(
select * , rn = ROW_NUMBER() over ORDER BY (articleid)
from articles
)
WHERE rn >= #LowerBound AND rn <= #UpperBound
RETURN
I guess you can make use of ROW_NUMBER Function something like this ....
;WITH OrderedData
AS
(
SELECT * , rn = ROW_NUMBER() OVER (ORDER BY SomeColumn)
FROM Table_Name
)
SELECT * FROM OrderedData
WHERE rn >= #LowerLimit AND rn <= #UpperLimit
Your Query
select * from articles
where articleid between #indexOfSelection AND #LimitOfselection
You just need to add the key word AND between your upper lower limit variable and upper limit variable.
Your Stored Procedure
CREATE PROCEDURE ordered_articles
#LowerBound int,
#UpperBound int
AS
BEGIN
SET NOCOUNT ON;
select * from articles
where articleid between #LowerBound and #UpperBound
END
To Select A range Of Rows
CREATE PROCEDURE ordered_articles
#LowerBound int,
#UpperBound int
AS
BEGIN
SET NOCOUNT ON;
WITH OrderedData
AS
(
SELECT * , rn = ROW_NUMBER() OVER (ORDER BY articleid)
FROM articles
)
SELECT * FROM OrderedData
WHERE rn >= #LowerBound AND rn <= #UpperBound
END
EXECUTE ordered_articles 10, 15 --<-- this will return 10 to 15 number row ordered by ArticleID
I want to store the top 2 results in 2 variables.
create table t(id int);
insert into t (id) values (1),(2),(3),(4);
declare #id1 int
declare #id2 int
select top 2 #id1 = first id,
#id2 = next id
from t
SQLFiddle
Can I do it in one query without using a loop?
declare #id1 int,#id2 int
;with cte as (
select top (2) id
from t
order by id
)
select #id1 = min(id), #id2 = max(id)
from cte
select #id1,#id2
Fiddle demo
with cte as (
select top 2 id, row_number() over(order by id) as rn
from t
order by id
)
select
#id1 = (select id from cte where rn = 1),
#id2 = (select id from cte where rn = 2)
or
with cte as (
select top 2 id, row_number() over(order by id) as rn
from t
order by id
)
select
#id1 = max(case when rn = 1 then id end),
#id2 = max(case when rn = 2 then id end)
from cte
sql fiddle demo
You can use LEAD() for SQL Server 2012.
SELECT TOP 1 #id1 = ID, #id2 = LEAD(ID) OVER (ORDER BY ID) FROM t
SQLFiddle Demo
With two SELECT it's easy...
DECLARE #id1 INT
DECLARE #id2 INT
SELECT TOP 1 #id1 = x.id
FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY id) RN FROM t) x
WHERE x.RN = 1
SELECT TOP 1 #id2 = x.id
FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY id) RN FROM t) x
WHERE x.RN = 2
SELECT #id1, #id2
With SQL 2012 you clearly could
SELECT #id1 = id
FROM t ORDER BY id OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY
SELECT #id2 = id
FROM t ORDER BY id OFFSET 1 ROWS FETCH NEXT 1 ROWS ONLY
Or evein in 2008 you could
; WITH Base AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY id) RN FROM t
)
SELECT #id1 = b1.id, #id2 = b2.id
FROM Base b1, Base b2
WHERE b1.RN = 1 AND B2.RN = 2
declare #id1 int
declare #id2 int
declare #table table(id int,rownum int)
insert into #table
select top 2 id,row_number() over( order by id) as rn from t
select #id1=case rownum when 1 then id else #id1 end,
#id2=case rownum when 2 then id end from #table
select #id1,#id2
SQL FIDDLE
More easy way with 2 selects:
declare #id1 int
declare #id2 int
select top 1 #id1 = id from t
select top 2 #id2 = id from t
select #id1, #id2
SQL Fiddle