I have data like this
Sr_No/ AccessionNo / Roll_nO / Price
---------------------------------------
1 / 101 / 45 / 1000
2 / 102 / 46 / 2000
3 / 101 / 43 / 500
I have written this query
select *
from Circulation
where MAX(sr_no) in (select *
from circulation
where accessionno = #accessionno)
I want to get values where the accession no is given by the textbox and it should be the the maximum value of Sr_No and for info Sr_NO is auto incremented.
My query is not working
I am a student and started c# quite a few months ago
Sorry for my bad english
I got this error
An aggregate may not appear in the WHERE
clause unless it is in a subquery contained in a HAVING clause or a select list, and the
column being aggregated is an outer reference.
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
I want that when I type 101 as accession no. so it will return this info
3 / 101 / 43 / 500
You probably wanted something like this:
SELECT *
FROM Circulation
WHERE sr_no = (SELECT MAX(sr_no)
FROM circulation
WHERE accessionno = #accessionno)
You want to select the row(s) from Circulation where the sr_no column equals the maximum of all sr_no values in your table - right?
SQL Server supports Common Table Expression and Window Function. ROW_NUMBER() will rank the SR_NO in descending order for every AccessionNo. So the value of 1 is given for the highest SR_NO per AccessionNo.
WITH records
AS
(
SELECT Sr_No, AccessionNo, Roll_nO, Price,
ROW_NUMBER() OVER(PARTITION BY AccessionNo ORDER BY Sr_No DESC) rn
FROM Circulation
)
SELECT Sr_No, AccessionNo, Roll_nO, Price
FROM records
WHERE rn = 1
But if an AccessionNo is already give, a simple TOP will do your job.
SELECT TOP 1 *
FROM Circulation
WHERE accessionno = #accessionno
ORDER BY Sr_no DESC
SELECT TOP 1 *
FROM Circulation
WHERE accessionno = #accessionno
ORDER BY Sr_no DESC
Also, it's best not to use SELECT * and instead use the column names.
Related
I want to get alternate series of records using SQL Server.
For example :
I want to skip first 10 records (1 to 10) in sequence and get other 10 records (11 to 20) after that I want to skip next 10 records (21 to 30) and get another next 10 records (31 to 40)
I have done for alternate rows as below...
SELECT ROW, EmployeeID
FROM
(SELECT
ROW_NUMBER() OVER (ORDER BY EmployeeID) AS ROW, *
FROM Employee) A
WHERE
ROW % 2 = 0
But in case of my requirement above logic will not work. Please help me to make above thing works..
Linq will also accepted
Thanks
SELECT ROW, EmployeeID
FROM
(SELECT
ROW_NUMBER() OVER (ORDER BY EmployeeID) AS ROW, *
FROM Employee) A
WHERE
((ROW - 1)/10) % 2 = 1
I have done above of your requirement like below (Example).
Generated 1200 number sequentially from 1 to 1200 like below
;WITH CTE
AS
(
SELECT 1 PERIOD_SID
UNION ALL
SELECT PERIOD_SID+1 FROM CTE WHERE PERIOD_SID<1200
)
SELECT * INTO #PERIOD1 FROM CTE
OPTION(MAXRECURSION 0)
After this i have find alternative numbers like you have mentioned in your query
SELECT PERIOD_SID FROM
(
SELECT CASE
WHEN PERIOD_SID%10 <> 0 THEN PERIOD_SID / 10
WHEN PERIOD_SID%10 = 0 THEN ( PERIOD_SID / 10 ) - 1
END RNO,
PERIOD_SID
FROM #PERIOD1 )A
WHERE RNO%2=0
so if you have sequential numbers in your query (If you dont have generate using rownumber) then apply above logic.
Your query need to convert like below.
SELECT EMPLOYEEID
FROM (SELECT Row_number()
OVER (
ORDER BY EMPLOYEEID)AS ROW,
*
FROM EMPLOYEE) A
WHERE ( CASE
WHEN RNO%10 <> 0 THEN RNO / 10
WHEN RNO%10 = 0 THEN ( RNO / 10 ) - 1
END )%2 = 0
may be you can try this
SELECT ROW, EmployeeID FROM(
SELECT ROW_NUMBER()OVER (ORDER BY EmployeeID)AS ROW,* FROM Employee)
A WHERE ((ROW - (ROW%10))/10) % 2 = 1
Don't if this works or not coz I dont have sql server to run. Please show the error/result after running this query.
Ask if any doubt.
I have this table in SQL Server:
ID | videoid | title
=========================
1 | id1 | title1
2 | id2 | title2
3 | id3 | title3
And I want to create select method that search in the title row with:
SELECT * FROM [movie].[dbo].[movies]
WHERE title like '%' + '%s' + '%'
And I'm looking for something like Limit in MySQL that from the SELECT results I will be able to get the 0-20,21-40,41-60 results.
Any help with this query?
I tried to use LIMIT 0, 10 and I received this error:
Could not find stored procedure 'LIMIT'.
You need to use TOP N with SQL SERVER.
SELECT TOP 10 * FROM [movie].[dbo].[movies]
WHERE title like '%' + '%s' + '%'
ORDER BY SomeColumn -- Specify your column for ordering
See: TOP (Transact-SQL)
Limits the rows returned in a query result set to a specified number
of rows or percentage of rows in SQL Server
Also look under Best Practices in docs.
In a SELECT statement, always use an ORDER BY clause with the TOP
clause. This is the only way to predictably indicate which rows are
affected by TOP.
If you are looking for Paging records then you will need ROW_NUMBER
In SQL Server 2012 a new feature was introduced that provides this functionality.
Look at the OFFSET part of the ORDER BY clause
SELECT *
FROM your_table
ORDER
BY some_column
OFFSET 20 ROWS
FETCH NEXT 10 ROWS ONLY
This will return the results 20-30 of your resultset (ordered by some_column)
For SQL Server 2005 - 2008R2 you can use windowed functions to perform the same action:
SELECT *
FROM (
SELECT *
, Row_Number() OVER (ORDER BY some_column) As sequence
FROM your_table
) As a_subquery
WHERE sequence >= 20
AND sequence <= 30
For versions of SQL Server prior to SQL Server 2005 there is no efficient way of achieving this effect. Here's something that does the trick:
SELECT *
FROM (
SELECT *
, (
SELECT Count(*)
FROM your_table As x
WHERE x.some_column <= your_table.some_column
) As sequence
FROM your_table
) As a_subquery
WHERE sequence >= 20
AND sequence <= 30
Final notes: for your results to be deterministic some_column should be unique. If it isn't then you need to add extra column(s) in to the equation to provide a deterministic sort order for your sequence.
Also note that SELECT * ... should be avoided in all production code. Don't be lazy [like I was in this answer ;-)] - list out only the columns required.
There's no equivalent in T-SQL. TOP allows you to get only the first x results from the result set. You can use a trick. Using ROW_NUMBER you can add a new column that starts from 1 and is incremented automatically.
Like this:
SELECT ROW_NUMBER OVER (SomeExpression), Field FROM ...
Then you can use
SELECT TOP x FROM
(
SELECT ROW_NUMBER OVER (ORDER BY ID) AS RowNumber, ID, videoid, title FROM ...
) tmp
WHERE RowNumber > Y ORDER BY RowNumber ASC
The trick is that this numbering is independent of the other fields, so using the same filter you'll always get the same RowNumbers and thus can filter again. This mimicks what LIMIT does.
For example, to get the entries 1 - 9 entries, you'd write:
SELECT TOP 9 FROM
(
SELECT ROW_NUMBER OVER (ORDER BY ID) AS RowNumber, ID, videoid, title FROM ...
) tmp
WHERE RowNumber >= 1 ORDER BY RowNumber ASC
Next Page:
SELECT TOP 9 FROM
(
SELECT ROW_NUMBER OVER (ORDER BY ID) AS RowNumber, ID, videoid, title FROM ...
) tmp
WHERE RowNumber >= 10 ORDER BY RowNumber ASC
Use Top:
SELECT TOP 1 * FROM [movie].[dbo].[movies]
WHERE title like '%' + '%s' + '%'
When TOP is used in conjunction with the ORDER BY clause, the result set is limited to the first N number of ordered rows; otherwise, it returns the first N number of rows in an undefined order.
Read more here.
To get results like 10-20, use ROW_NUMBER:
SELECT TOP 10 * FROM
(SELECT ROW_NUMBER() OVER (id_field) as SlNo, ID, videoid, title
FROM TableName) T
WHERE SlNo>=10
ORDER BY id_field
I dont't think there's LIMIT in SQL server. Use TOP instead. TOP returns the first N rows of a query, so if it's TOP 10, even if you have a thousand rows, it will only return the first 10. Try this...
SELECT TOP 60 *
FROM [movie].[dbo].[movies]
WHERE title like '%' + '%s' + '%'
You can use following method for this purpose:
Method 1: ORDER BY
SELECT *
FROM [movie].[dbo].[movies]
WHERE title like '%' + '%s' + '%'
ORDER BY ID OFFSET 21 ROWS FETCH NEXT 20 ROWS ONLY
Method 2: ROW_NUMBER
SELECT *
FROM ( SELECT *,
ROW_NUMBER()OVER (ORDER BY ID)row
FROM [movie].[dbo].[movies]
WHERE title like '%' + '%s' + '%'
)z
WHERE row>20
AND row<=40
Method 3: Top N
SELECT TOP 20 *
FROM ( SELECT TOP 40 *
FROM [movie].[dbo].[movies]
WHERE title like '%' + '%s' + '%'
ORDER BY ID
)z
ORDER BY ID DESC
I am working on online question application.
I am Fetching Records from a database.
I have SQL database holding 1000 question in 10 set. I mean each set containing 100 questions. How can I take 20 random questions from each set? I mean how can I select 2 (as per request) random question from each set?
Try:
SELECT TOP 20 * FROM [YourTable] ORDER By NEWID()
More About NEWID().
If you need to get 20 random questions from each group here is an SQLFiddle example. SetNum here is a set ID
select * from
(
select t.*,
ROW_NUMBER()
over (partition by setNum order by NewId()) rNum from t
) t2 where rNum<=20
Try this if you want 2 random questions from each SET...
SELECT TOP 2 * FROM (SELECT * FROM [YourTable] WHERE SET_ID = 1) ORDER By NEWID()
UNION
SELECT TOP 2 * FROM (SELECT * FROM [YourTable] WHERE SET_ID = 2) ORDER By NEWID()
UNION
.
.
.
.
UNION
SELECT TOP 2 * FROM (SELECT * FROM [YourTable] WHERE SET_ID = 10) ORDER By NEWID()
I would like to have your assistance in order to know if it's possible to achieve the desired query without needing a stored procedure. I will try to explain myself as good as I can.
I have a similar structure to this:
PK / FK / DateTime / Value
1 / 68 / 10:30 / 60.5
2 / 68 / 09:30 / 10.5
3 / 61 / 05:30 / 01.0
4 / 58 / 04:30 / 22.2
5 / 58 / 01:00 / 15.0
These rows are defining some kind of event wich is described by the foreign key (FK). What I want to achieve is to get the two most recent rows for a set of events (FK).
Some kind of
SELECT TOP 2 *
FROM TABLE
WHERE FK IN (68,58)
ORDER BY DATETIME DESC
, but obtaining two rows of every FK in the IN clause.
In natural language, the desired operation is to iterate through FK in the IN clause and make a
SELECT TOP 2 *
FROM TABLE
ORDER BY DATETIME DESC.
I would like to know if it's possible to express that in one SQL.
Thanks a lot,
One option
SELECT
B.*
FROM
(SELECT DISTINCT FK FROM MyTable) A
CROSS APPLY
(
SELECT TOP 2 *
FROM TABLE T
WHERE T.FK = A.FK
ORDER BY DATETIME DESC
) B
Or
;WITH CTE AS
(
SELECT *
ROW_NUMBER() OVER (PARTITION BY FK ORDER BY DATETIME DESC) AS RowNum
FROM
Table
)
SELECT * FROM CTE WHERE RowNum <= 2
SELECT d.*
FROM(
SELECT DISTINCT FK FROM YourTable
) AS y
OUTER APPLY(
SELECT TOP 2 *
FROM YourTable AS y1
WHERE y1.FK = y.FK
ORDER BY DATETIME DESC
) AS d
SELECT D.*
FROM (
SELECT t.*
, ROW_NUMBER = ROW_NUMBER() OVER (
PARTITION BY FK
ORDER BY DateTime DESC
)
FROM Table AS t
) AS D
WHERE D.ROW_NUMBER <= 2
Or user RowNumber
You can always use a union:
SELECT TOP 2 * FROM TABLE WHERE FK = 68 ORDER BY DATETIME DESC
UNION
SELECT TOP 2 * FROM TABLE WHERE FK = 58 ORDER BY DATETIME DESC
In essence I want to pick the best match of a prefix from the "Rate" table based on the TelephoneNumber field in the "Call" table. Given the example data below, '0123456789' would best match the prefix '012' whilst '0100000000' would best match the prefix '01'.
I've included some DML with some more examples of correct matches in the SQL comments.
There will be circa 70,000 rows in the rate table and the call table will have around 20 million rows. But there will be a restriction on the Select from the Call table based on a dateTime column so actually the query will only need to run over 0.5 million call rows.
The prefix in the Rate table can be up to 16 characters long.
I have no idea how to approach this in SQL, I'm currently thinking of writing a C# SQLCLR function to do it. Has anyone done anything similar? I'd appreciate any advice you have.
Example Data
Call table:
Id TelephoneNumber
1 0123456789
2 0100000000
3 0200000000
4 0780000000
5 0784000000
6 0987654321
Rate table:
Prefix Scale
1
01 1.1
012 1.2
02 2
078 3
0784 3.1
DML
create table Rate
(
Prefix nvarchar(16) not null,
Scale float not null
)
create table [Call]
(
Id bigint not null,
TelephoneNumber nvarchar(16) not null
)
insert into Rate (Prefix, Scale) values ('', 1)
insert into Rate (Prefix, Scale) values ('01', 1.1)
insert into Rate (Prefix, Scale) values ('012', 1.2)
insert into Rate (Prefix, Scale) values ('02', 2)
insert into Rate (Prefix, Scale) values ('078', 3)
insert into Rate (Prefix, Scale) values ('0784', 3.1)
insert into [Call] (Id, TelephoneNumber) values (1, '0123456789') --match 1.2
insert into [Call] (Id, TelephoneNumber) values (2, '0100000000') --match 1.1
insert into [Call] (Id, TelephoneNumber) values (3, '0200000000') --match 2
insert into [Call] (Id, TelephoneNumber) values (4, '0780000000') --match 3
insert into [Call] (Id, TelephoneNumber) values (5, '0784000000') --match 3.1
insert into [Call] (Id, TelephoneNumber) values (6, '0987654321') --match 1
Note: The last one '0987654321' matches the blank string because there are no better matches.
Since this is based on partial matching, a subselect would be the only viable option (unless, like LukeH assumes, every call is unique)
select
c.Id,
c.TelephoneNumber,
(select top 1
Scale
from Rate r
where c.TelephoneNumber like r.Prefix + '%' order by Scale desc
) as Scale
from Call c
SELECT t.Id, t.TelephoneNumber, t.Prefix, t.Scale
FROM
(
SELECT *, ROW_NUMBER() OVER
(
PARTITION BY c.TelephoneNumber
ORDER BY r.Scale DESC
) AS RowNumber
FROM [call] AS c
INNER JOIN [rate] AS r
ON c.TelephoneNumber LIKE r.Prefix + '%'
) AS t
WHERE t.RowNumber = 1
ORDER BY t.Id
Try this one:
select Prefix, min(c.TelephoneNumber)
from Rate r
left outer join Call c on c.TelephoneNumber like left(Prefix + '0000000000', 10)
or c.TelephoneNumber like Prefix + '%'
group by Prefix
You can use a left join to try to find a "better" match, and then eliminate such matches in your where clause. e.g.:
select
*
from
Call c
inner join
Rate r
on
r.Prefix = SUBSTRING(c.TelephoneNumber,1,LEN(r.Prefix))
left join
Rate r_anti
on
r_anti.Prefix = SUBSTRING(c.TelephoneNumber,1,LEN(r_anti.Prefix)) and
LEN(r_anti.Prefix) > LEN(r.Prefix)
where
r_anti.Prefix is null