Linq to dataset and display linq result in repeater control - c#

I need to display distinct rows, which actually should get 1 latest rows for each year based for date fields.
I tried to get resolve this using CTE but on further testing it is not working properly as it will gets only the ROW based on ROWNumber and if we use filter then it doesn't get the desired results.
So i thought of getting the AlbumID, AlbumName, AlbumDate and AlbumYear_YYYY from table and pass it to dataset and then use LINQ againt this dataset to further get the unique rows based on latest album for the year YEAR only
Assuming my Table has following rows
AlbumID, AlbumName, AlbumDate , AlbumIcon
MY MS-SQL query
string sql= "SELECT AlbumID, AlbumName, AlbumIcon, AlbumDate, DATEPART(YYYY, AlbumDate) AS Year FROM PhotoAlbumName "
DataSet ds = DataProvider.Connect_Select(strSql);
DataView dv = ds.Tables[0].DefaultView;
//DO LINQ HERE and pass the value of linq to Pager control
PagerControl1.BindDataWithPaging(rptAlbumsCategories, dv.Table);
I am not sure how to do this but if it works then it will eliminate the unwanted result which happens due to following sql query.
;WITH DistinctYEAR AS
(
SELECT AlbumID, AlbumIcon, AlbumDate, AlbumVisible,AlbumName,
ROW_NUMBER() OVER(PARTITION BY DATEPART(YYYY,AlbumDate) ORDER BY AlbumDate) AS 'RowNum'
FROM PhotoAlbumName
)
SELECT * FROM DistinctYEAR WHERE RowNum = 1 AND AlbumVisible = 1 ORDER BY AlbumDate DESC
UPDATE:

I'm not sure but i assume that your cte is incorrect. You should apply the WHERE AlbumVisible = 1 on the CTE not on the outer SELECT:
;WITH DistinctYEAR AS
(
SELECT AlbumID, AlbumIcon, AlbumDate, AlbumVisible,AlbumName,
ROW_NUMBER() OVER(PARTITION BY DATEPART(YYYY,AlbumDate) ORDER BY AlbumDate) AS 'RowNum'
FROM PhotoAlbumName
WHERE AlbumVisible = 1
)
SELECT dy.*
FROM DistinctYEAR dy
WHERE RowNum = 1
ORDER BY AlbumDate DESC

Related

How to create a ROWNUMBER column that always keeps a column of sequential numbers from 1 to N. The count of the column

In SQL Server, I am trying to create a column of sequential numbers to help me with my code. I am not sure how to create a column that is always populated with a sequential set of numbers starting from 1.
1
2
3
N
SqlCommand command = new SqlCommand("SELECT *, ROW_NUMBER() OVER(ORDER BY Id) AS RowRankNumber FROM Statements WHERE RowRankNumber >= "+1+" AND RowRankNumber <= "+4+"", con);
You need to use inner query to get the result. In your query the you can't use row_number in where clause. For example
SELECT * FROM (
SELECT ROW_NUMBER() OVER(ORDER BY Id) AS RowRankNumber,* FROM Statements
) x WHERE RowRankNumber >=1 AND RowRankNumber <=4

How to select +1 record from MSSQL using EF with single query?

In short:
I have records that have CreationTime column in database. I want to select records from last 2 days PLUS one record that follows (sort by creation date desc) that can be any time old.
So from records (knowing that today date is 11th March) I want to select all records that are at max 2 days old + 1:
1. 2019-03-11
2. 2019-03-11
3. 2019-03-10
4. 2019-03-08
5. 2019-03-07
6. 2019-03-16
So result should contain records 1,2,3,4. (4. even though it is 3 days old, it is that "+1" record I need).
I'm using MSSQL and .NET 4.6.1 Entity Framework.
IMO cleaner way to achieve this is to write two queries: first to get data from last two days and second is to get the latest record older than 2 days.
To get records from last 2 days:
select * from MyTable where CreationTime between getdate() and getdate() - 2
To get additional record:
select top 1 * from MyTable where CreationTme < getdate() - 2 order by CreationTime desc
Using EF with LINQ methods (dc is database context):
To get records from last 2 days:
dc.Entitites.Where(e => e.CreationTime <= DateTime.Now && e.CreationTime >= DateTime.Now.AddDays(-2));
additional record:
dc.Entities.Where(e => e.CreationTime < DateTime.Now.AddDays(-2)).OrderByDescending(e => e.CreationTime).First();
Try the following Logic
DECLARE #T TABLE
(
SeqNo INT IDENTITY(1,1),
MyDate DATETIME
)
INSERT INTO #T
VALUES(GETDATE())
,(DATEADD(MINUTE,-23,GETDATE()))
,(DATEADD(MINUTE,-78,GETDATE()))
,(DATEADD(MINUTE,-5443,GETDATE()))
,(DATEADD(MINUTE,-34,GETDATE()))
,(DATEADD(MINUTE,-360,GETDATE()))
,(DATEADD(MINUTE,-900,GETDATE()))
,(DATEADD(MINUTE,-1240,GETDATE()))
,(DATEADD(MINUTE,-3600,GETDATE()))
;WITH CTE
AS
(
SELECT
RN = ROW_NUMBER() OVER(PARTITION BY CAST(MyDate AS DATE) ORDER BY MyDate DESC),
DateSeq = DATEDIFF(DAY,MyDate,GETDATE()),
*
FROM #T
)
SELECT
*
FROM CTE
WHERE
DateSeq <2
OR
(
DateSeq = 2
AND
RN = 1
)
You can try the following query.
DECLARE #table TABLE(StartDate DATETIME)
INSERT INTO #table
VALUES('2019-03-11'),('2019-03-11'),('2019-03-10'),
('2019-03-08'),('2019-03-07'),('2019-03-16')
SELECT * FROM #table WHERE StartDate BETWEEN GETDATE()-4 AND GETDATE()
For getting old 4th entry,
SELECT * FROM #table
ORDER BY (select null)
OFFSET (select Count(*) from #table where StartDate BETWEEN GETDATE()-2 AND
GETDATE()) ROWS
FETCH NEXT 1 ROWS ONLY

SQL Server : sorting a distinct table which has XML column

I have a table which I need to do a distinct on as it has some duplicates and then needs to sort it and join the XML into one column.
Here is what I tried :
Select *
From TableA
Where TableID ='1234'
And Convert(nvarchar(max), xmlcolumn) in (Select Distinct Convert(nvarchar(max), xmlcolumn))
The above does sort out the list for me nor it removes the duplicates.
Select distinct convert (nvarchar(max), xmlcolumn)
From TableA
Where TableID ='1234'
Order By TableID
The above returns what is required, but if I do an order by (as shown above) I get an error:
ORDER by items must appear in the select list if select district is specified
I don't want to enter the TableID in the select statement because I don't want this in the results. Secondly, how do I convert the XML (which is converted to nvarchar to do the distinct) back to XML for exporting to C#.
If i understand correctly, you could remove duplicate rows by using ROW_NUMBER like this
DECLARE #SampleData AS TABLE
(
TableID varchar(10),
ColumnA int,
ColumnB varchar(10),
XmlColumn xml
)
;WITH temp AS
(
SELECT sd.TableID,
CAST(sd.XmlColumn AS nvarchar(max)) AS XmlColumn,
ROW_NUMBER() OVER(PARTITION BY CAST(sd.XmlColumn AS nvarchar(max)) ORDER BY sd.TableID) AS Rn
FROM #SampleData sd
Where TableID = '1234'
)
SELECT t.XmlColumn
FROM temp t
WHERE Rn = 1 -- remove duplicate rows
ORDER BY t.TableID -- order by any columns

Getting error of "Top clause contains invalid value" on front end but in SQL Data is clearly visible

While binding data to Dataview getting this error but Parameters are correctly sending there values.
Seems DBhelper class is throwing this error but don't know why
My procedure:
insert #leads(opp_lead,opp_NAME,CNT)
select opp_lead,'LEAD'+opp_lead,COUNT(*) from #pipeline GROUP BY opp_lead
UPDATE #leads SET opp_NAME=CONTACT_NAME FROM TBLCONTACT C, #leads L WHERE CONVERT(VARCHAR(50),L.opp_lead)=CONVERT(VARCHAR(50),C.CONTACT_ID)
COUNT(*) DESC
create table #YearlyEndCampaign
(
slno INT ,
lvl int
)
SELECT TOP 1 #MAXLEADS=COUNT(*) FROM #pipeline GROUP BY opp_lead ORDER BY COUNT(*) DESC
INSERT INTO #YearlyEndCampaign(slno,LVL)
SELECT SEQ,0 FROM (SELECT TOP (#MAXLEADS) seq = ROW_NUMBER() OVER (ORDER BY number) FROM [master]..spt_values)S
C# code:
long businessID = Convert.ToInt64(Session["BusinessID"]);
long YEAR = Convert.ToInt64(2015);
long UserID = Convert.ToInt64(Session["Contact_ID"]);
BeggingDA objBeggingDA = new BeggingDA();
DataView dv = (new BeggingDA()).BeggingLoadByBusinessID(YEAR, businessID, UserID);
As you say, the first SELECT TOP 1 #MAXLEADS=COUNT(*) FROM #pipeline statement is not returning any data. This means that #MAXLEADS is null.
If you then run select top (NULL) FROM [master]..spt_values you will get the TOP clause contains an invalid value error, because you are not passing a numeric value to TOP.
The solution is to check if #MAXLEADS is null before doing the insert - if there aren't any rows, you would be selecting top 0, so it is pointless doing the insert anyway. A simple IF #MAXLEADS IS NOT NULL should be sufficient:
SELECT TOP 1 #MAXLEADS=COUNT(*) FROM #pipeline GROUP BY opp_lead ORDER BY COUNT(*) DESC
IF #MAXLEADS IS NOT NULL BEGIN
INSERT INTO #YearlyEndCampaign(slno,LVL)
SELECT SEQ,0 FROM (SELECT TOP (#MAXLEADS) seq = ROW_NUMBER() OVER (ORDER BY number) FROM [master]..spt_values)S
END

how to page and query large data in c#

I need to query large amount of data from a database via C# and ADO.NET (IDbDataReader and IDbCommand API).
I've created a query like the follwing:
WITH v as
(SELECT myFields, Datefield
ROW_NUMBER() OVER (ORDER BY Datefield ASC) AS CurrentRow
FROM dbTable
WHERE /**/
AND Datefield BETWEEN #pStart AND #pEnd
// ... )
SELECT myFields, Datefield from v where CurrentRow
BETWEEN #pRowStart AND #pRowEnd
From the results I have to use an C# API which will transform and generate new data,
thats why an SqlServer - only solution can't be used.
I want to query against the database with a pagesize of 10000 until there is no more data.
Something like
while (true)
{
// ... execute reader
if (reader.HasRows)
break;
}
will not work cause I have to use the IDbDataReader interface.
What can I do in my situation?
EDIT + Solution
I iterate over each block in a while loop and check HasRows property of the datareader, cause i can use the specialized type.
On SQL Server 2012 you can use the OFFSET and FETCH clauses for simple and efficient paging, as shown in the ORDER BY clause examples:
SELECT DepartmentID, Name, GroupName
FROM HumanResources.Department
ORDER BY DepartmentID ASC
OFFSET #StartingRowNumber - 1 ROWS
FETCH NEXT #RowCountPerPage ROWS ONLY;
On previous versions you can use a CTE and ROW_NUMBER() to calculate a number for each row and limit the results:
WITH OrdersRN AS
(
SELECT ROW_NUMBER() OVER(ORDER BY OrderDate, OrderID) AS RowNum
,OrderID
,OrderDate
,CustomerID
,EmployeeID
FROM dbo.Orders
)
SELECT *
FROM OrdersRN
WHERE RowNum BETWEEN (#PageNum - 1) * #PageSize + 1
AND #PageNum * #PageSize
ORDER BY OrderDate ,OrderID;

Categories