I have a database table like this:
I want to get the the row number of the second row. I use the following code:
SELECT ROW_NUMBER() OVER(ORDER BY Name) From Deposit WHERE Name='Murali'
But, its not working. Whats wrong with the code?
Thanks in advance.
The ROW_NUMBER function returns the row number in the resulting dataset.
In your query you restricted the results to only those whose name is Murali. Since you have only one such record, it is normal that it will return 1.
In SQL there's no such notion as row number. Table rows do not have an order. The notion of order only makes sense when you make a SQL query. Without SQL query you simply cannot talk about order and row numbers.
It appears that you need to introduce some order number for each user. The correct way to implement this is to add an Order column to your Deposit table. Now in order to retrieve it you would use the following query:
SELECT [Order] From Deposit WHERE Name = 'Murali'
All that's left is make the Order column to autoincrement and you are good to go. Everytime a new record is inserted the value will be automatically incremented. So there you go, now you have an order which represents the order in which the records have been inserted into the table. You now have context.
Perhaps something like this (if I understood you correctly):
SELECT Q.RN FROM (
SELECT ROW_NUMBER() OVER(ORDER BY Name) AS RN, * From Deposit
) AS Q
WHERE Q.Name = 'Murali'
Try this
WITH TempTable AS
(
SELECT Name,ROW_NUMBER() OVER (ORDER BY Name) AS 'RowNumber'
FROM Deposit
)
SELECT RowNumber,Name
FROM TempTable
WHERE Name='Murali'
Related
I need some help with the query,
I have a products Table.
I need to select all columns (No Duplicates for 'Barcode')
also I need to know how many duplicates were found for each 'barcode'...?
Heres What i have:
ID-----BarCode------Date------ProductType------Status------Serial ...etc.....
1------BarAA---------Jan1------Simple-------------Saleble------843573857
2------BarBB--------Jan2------Unqie---------------Saleble------87686585647
3------BarCC--------Jan9------Unqie---------------Saleble------456365677
4------BarCC--------Jan5------Unqie---------------Saleble------3415435437
5------BarCC--------Jan7------Unqie---------------Saleble------fdgsfdg4t
6------BarDD--------Jan6------Unqie---------------Saleble------435tergdf
7------BarDD--------Jan9------Unqie---------------Saleble------mgdnfdfsg
8------BarDD--------Jan4------Unqie---------------Saleble------sdfwr534ew
I need:
count----ID-----BarCode------Date------ProductType------Status------Serial ...etc.....
1---------1------BarAA---------Jan1------Simple-------------Saleble------843573857
1---------2------BarBB--------Jan2------Unqie---------------Saleble------87686585647
3---------3------BarCC--------Jan9------Unqie---------------Saleble------456365677
3---------6------BarDD--------Jan6------Unqie---------------Saleble------435tergdf
It's not easy to determine what exactly you mean or you're having trouble with without code to look at. I'm including the T-SQL Code for you'll need to get one row per barcode and also how many duplicates exist per barcode for barcodes that are duplicated.
WITH ProductsCTE AS
(
SELECT
ROW_NUMBER() OVER (PARTITION BY Barcode ORDER BY Barcode) Instance, *
FROM
dbo.Products
)
SELECT * FROM ProductsCTE WHERE ProductsCTE.Instance = 1;
The above code snippet will only get 1 row per unique barcode. So if you can load your products from that query you'll have no duplicates as far as the barcode is concerned.
For determining how many entries you have per barcode, consider the following code.
SELECT
p.Barcode, COUNT(*) NumberOfEntries
FROM
dbo.Products p
GROUP BY
p.Barcode
HAVING -- You can leave the HAVING clause out if you want to include unique ones
COUNT(*) > 1
first of all I am sorry if this question is too obvious, since I am quite new in SQL.
So, I have a list of IDs (variable, depending how many products the user chooses). And I want to check if all of them are in a table. If one of them is not, the result of the query should be null. If all of them are there, the result should be all the rows where those IDs are.
How can I do this?
Best regards,
Flavio
Do a LEFT JOIN from the list to the table on the ID field. You'll get a null if there is no record
You can even put a WHERE clause like 'WHERE List.ID IS NULL' to only see those that aren't in the table
Edit: Original Poster did not say they were using C# when I wrote this answer
UNTESTED:
Not sure if this is the most efficient but it seems like it should work.
1st it generates a count of items in the table for your list. Next it cross joins the 1 result record to a query containing the entire list ensuring the count matches the count in your provided list and limiting the results to your list.
SELECT *
FROM Table
CROSS JOIN (
SELECT count(*) cnt
FROM table
WHERE ID in (yourlist)) b
WHERE b.cnt = yourCount
and ID IN (YourList)
Running two in statements seems like it would be terribly slow overall; but my first step when writing SQL is usually to get something that works and then seek to improve performance if needed.
Get the list of Ids into a table, (you can pass them as a table variable parameter to a Stored proc), then in the stored proc, write
assuming the list of ids from C# is in table variable #idList
Select * from myTable
Where id in (Select id from #idList)
and not exists
(Select * from #idList
where id Not in
(Select id from myTable))
I have the following query which works in SQL Server :-
query = "select * from (select *,ROW_NUMBER() OVER (ORDER BY LogDate)
AS ROW_NUM from table1) x where ROW_NUM>0";
But I want this in Access OLEDB, which doesn't support ROW_NUMBER() function.
What is another way to get ROW NUMBER in OLEDB Provider?
Access does not support rownum. You could add a column called ID which would use AutoIncrement to simulate a row number. But if a record is removed from the table the ID will not change, meaning a ID will be missing from your records.
This anwser also explores some possibilities:
How to use the same function like Oracle Rownum in MS ACCESS
In my project I need to insert a table data from another table. I trying to write this sql code. But this order by option is not working while inserting the data. Here is my code:
INSERT INTO StudentInfo_MeritPosition
( ID,
Name,
MeritPosition,
SSC,
HSC,
First,
Second,
Third,
Fourth,
Fifth
)
SELECT ID,
Name,
MeritPosition,
SSC,
HSC,
First,
Second,
Third,
Fourth,
Fifth
FROM StudentInfo
ORDER BY MeritPosition
The above code inserting data into database. But not in the order format.
I need to know if there any way our for this problem. Thank you.
SQL tables represent unordered sets. When you retrieve data from the table, the data has no particular order, unless you specify order by. So, you can just retrieve the data as:
select mp.*
from StudentInfo_MeritPosition mp
order by mp.MeritPosition;
You can make this query more efficient by adding an index on StudentInfo_MeritPosition(MeritPosition).
You can use a temp table to order in any way you want. In my opinion it's easier to assemble a temp table first, then order those results and select them into the table you're trying to populate in a given order. This way you can translate it to a stored procedure and feed it the parameter of "column name" and "ASC or DESC." The temp table will take a bit longer to work with since you're selecting, ordering, reselecting, and inserting. However, the end result is much more robust than a 1 time query allowing you to use any column name, and ASC or DESC. Just remember that when you do select the results into your permanent table, you leave out the primary key (typically [P_ID]) column form your select into statement.
So, to improve on Gordon's answer, you could write something like what follows:
DECLARE #fromTbl, #sortCol, #orderByCol VARCHAR(50)
EXEC('
select mp.*
from /* StudentInfo_MeritPosition* / ' + #fromTbl + 'mp
order by /* mp.MeritPosition */ mp.' + #orderByCol + ' ' + #sortOrder;'
/* If you wanted to debug it and make sure your parameters are being
generated correctly, you can use the PRINT function instead of
Exec('Your statement above') */
Then, if you turn it into a SP you can pass in the three parameters table, order by column, and sort order (ASC|DESC) and bypass the temp table creation process I mentioned previously.
Try this.
INSERT
/*+append*/
INTO StudentInfo_MeritPosition
( ID,
Name,
MeritPosition,
SSC,
HSC,
First,
Second,
Third,
Fourth,
Fifth
)
SELECT *
FROM (
SELECT ID,
Name,
MeritPosition,
SSC,
HSC,
First,
Second,
Third,
Fourth,
Fifth
FROM StudentInfo
ORDER BY MeritPosition );
I am inserting records through a query similar to this one:
insert into tbl_xyz select field1 from tbl_abc
Now I would like to retreive the newly generated IDENTITY Values of the inserted records. How do I do this with minimum amount of locking and maximum reliability?
You can get this information using the OUTPUT clause.
You can output your information to a temp target table or view.
Here's an example:
DECLARE #InsertedIDs TABLE (ID bigint)
INSERT into DestTable (col1, col2, col3, col4)
OUTPUT INSERTED.ID INTO #InsertedIDs
SELECT col1, col2, col3, col4 FROM SourceTable
You can then query the table InsertedIDs for your inserted IDs.
##IDENTITY will return you the last inserted IDENTITY value, so you have two possible problems
Beware of triggers executed when inserting into table_xyz as this may change the value of ##IDENTITY.
Does tbl_abc have more than one row. If so then ##IDENTITY will only return the identity value of the last row
Issue 1 can be resolved by using SCOPE__IDENTITY() instead of ##IDENTITY
Issue 2 is harder to resolve. Does field1 in tbl_abc define a unique record within tbl_xyz, if so you could reselect the data from table_xyz with the identity column. There are other solutions using CURSORS but these will be slow.
SELECT ##IDENTITY
This is how I've done it before. Not sure if this will meet the latter half of your post though.
EDIT
Found this link too, but not sure if it is the same...
How to insert multiple records and get the identity value?
As far as I know, you can't really do this with straight SQL in the same script. But you could create an INSERT trigger. Now, I hate triggers, but it's one way of doing it.
Depending on what you are trying to do, you might want to insert the rows into a temp table or table variable first, and deal with the result set that way. Hopefully, there is a unique column that you can link to.
You could also lock the table, get the max key, insert your rows, and then get your max key again and do a range.
Trigger:
--Use the Inserted table. This conaints all of the inserted rows.
SELECT * FROM Inserted
Temp Table:
insert field1, unique_col into #temp from tbl_abc
insert into tbl_xyz (field1, unique_col) select field1, unique_col from tbl_abc
--This could be an update, or a cursor, or whatever you want to do
SELECT * FROM tbl_xyz WHERE EXISTS (SELECT top 1 unique_col FROM #temp WHERE unique_col = tbl_xyz.unique_col)
Key Range:
Declare #minkey as int, #maxkey as int
BEGIN TRANS --You have to lock the table for this to work
--key is the name of your identity column
SELECT #minkey = MAX(key) FROM tbl_xyz
insert into tbl_xyz select field1 from tbl_abc
SELECT #maxkey = MAX(key) FROM tbl_xyz
COMMIT Trans
SELECT * FROM tbl_xyz WHERE key BETWEEN #minkey and #maxkey