SQL query for paging received records - c#

I want to write a query that receives informations about customers and their orders from another table and show them in this way:
Customer 1
Customer 1 Order 1
Customer 1 Order 2
Customer 2
Order 1 Customer 2
Customer 3
Order 1 Customer 3
....
And I want to do paging by Customers. For example - if I define items per page = 10, I want to show 10 customers, no matter how many orders they had.
I prepared this query but I think it's not gonna work properly and I don't know how to solve this..
var result = db.Page<Customer>(pageNumber, 10, "SELECT c.*, o.* FROM Customers c JOIN Orders o
ON o.Id = c.Id");

You can use dense_rank() and filter on that:
SELECT c.*, o.*, DENSE_RANK() OVER (ORDER BY c.id) as seqnum
FROM Customers c JOIN
Orders o
ON o.Customer_Id = c.Id;
You need to use WHERE for filtering, rather than LIMIT or FETCH or whatever.

Related

EF Core/SQL Join a different entity based on a condition

Lets suppose I have a table called Transactions
Transactions has the following columns
OrderId,
OrderType (Can be 0 = Sale or 1 = Purchase) <--- this can increase
Amount
Now I want to get the relevant data based on the OrderType
if OrderType = 0 then join from Sale Table else Join from Purchase Table.
Currently what I am doing is that doing three calls to the database to get the some other values from the other tables(which works but highly inefficient in long run as 3 Calls are bad performance wise).
My solution is using left join with SQL
SELECT ap.*,
coalesce(s.orderNo,p.orderNo) as orderNo
FROM apptransactions AS ap
LEFT JOIN sales AS s ON (ap.orderType = 0 and ap.orderId = s.id)
LEFT JOIN purchases AS p ON (ap.orderType = 1 and ap.orderId = p.id);
how can this query be converted to EF Core?
Why is your query not like this?
var results = context.Transactions.Select(t =>
new
{
/* t.column list, there's no t.* in LINQ */,
OrderNo = t.OrderType == 0 ? t.Sale.OrderNo : t.Purchase.OrderNo
});
Let EF generate any underlying joins it needs to, concern yourself with getting the results you want.
This also alludes to what #caius mentions. Your model is likely not high level enough or incorrectly mapped.

Having count on result of Group_Concat

I have applied the Group_Concat on my query and the results are displayed just fine. Below is my query,
SELECT tblUserGroup.GroupID, GROUP_CONCAT(tblUserGroup.UserId) AS UserIds FROM
tblGroup
INNER JOIN tblUserGroup ON tblGroup.GroupID = tblUserGroup.GroupID
GROUP BY tblUserGroup.GroupID
ORDER BY (UserIds)
NOW the ouput is something like this.
GroupID UserIds
1 1,2
2 1,4
3 1,2,3
4 1,2
5 1,2
6 1,2,3
I have read different questions on GROUP_CONCAT and COUNT but I want to apply count not on UserId rather I want to apply count on theGROUP_CONCAT such as "1,2".
What I want is to modify this query such that it only display those records which occurs more then one time. For example just 1,2 and 1,2,3
Have you tried to use subquery? It would be something like:
SELECT Sub.UserIds, COUNT(*) as Qt
FROM (
SELECT tblUserGroup.GroupID, GROUP_CONCAT(CONVERT(tblUserGroup.UserId, CHAR(20)) SEPARATOR ',') AS UserIds, count(*) FROM
tblGroup
INNER JOIN tblUserGroup ON tblGroup.GroupID = tblUserGroup.GroupID
GROUP BY tblUserGroup.GroupID HAVING COUNT(*) > 0
) AS Sub
GROUP BY Sub.UserIds
Maybe you can use count and use below query (I could not test it):
SELECT tblUserGroup.GroupID, GROUP_CONCAT(tblUserGroup.UserId) AS UserIds, count(*) FROM
tblGroup
INNER JOIN tblUserGroup ON tblGroup.GroupID = tblUserGroup.GroupID
GROUP BY tblUserGroup.GroupID HAVING COUNT(*) > 0
ORDER BY (UserIds)

Select distinct duplicated rows from 1:n tables in SQL Server

I am trying to select customers and their orders in one query, but I get customer and his orders in datatable which customer table columns repeated for each order.
I tried DISTINCT, GROUP BY but can't do it.
SQL:
select *
from Customer, Order
where Order.CustomerID = Customer.CustomerID
and Customer.CustomerID = '2'
Tables:
Since there cannot be different columns for each row you can't do it without having duplicates. Consider reading data separately, once for the customer and once for her orders.
i want to get all customers and orders the query count will grow.if i
have 3 customer i want to get orders and customers in one query.not 6
times query execution.
You do not need to perfrom a separate query for each customer. You just need a single query for all customers and a single query for all orders. Then you may connect them in application layer rather than a single query.
But if you argue that you have too many customers and too many orders to hold them all in memory, well, then you may perform a separate query for each customer. That's a tradeoff between memory and CPU.
This is a very rare query, but this my understanding of your need :p.
select *
from (
select 'CustomerID' as col1, 'CustomerName' as col2, 'ContactName' as col3,
'Address' as col4, 'City' as col5, 'PostalCode' as col6, 'Country' as col7, 0 as ord
union all
select CustomerID, CustomerName, ContactName, Address, City, PostalCode, Country, 1 as ord
from Customers
union all
select 'OrderId', 'CustomerID', 'EmployeeID', 'OrderDate', 'ShipperID', Null, Null, 0 as ord
union all
select OrderId, CustomerID, EmployeeID, OrderDate, ShipperID, Null, Null, 2 as ord
from Orders) res
In the result with ord = 0 you have titles, with ord = 1 you will have customers only and with ord = 2 you will have orders, and you can use this query with this condition:
where (col1 = #customerId and ord = 1) or (col2 = #customerId and ord = 2)
You can add or ord =0 if you want to add titles in your output.

.NET LINQ , List of Orders grouped by CustomerId across three tables?

I have three tables in my SQL-database
Orders (Id, Value, Timestamp)
Customer(Id, Firstname, Lastname)
OrderCustomer(Id, CustomerId, OrdersId)
I want to achieve that I get a list of results where each object got a customerid and the related orders of that customer.
I have seen this example at MSDN.com, which is nearly what I need, but only with 2 tables:
Dim customerList = From cust In customers
Group Join ord In orders On
cust.CustomerID Equals ord.CustomerID
Into CustomerOrders = Group,
OrderTotal = Sum(ord.Total)
Select cust.CompanyName, cust.CustomerID,
CustomerOrders, OrderTotal
My code right now only gives me a list with all the customers and an order, but they are not grouped together.
So its like:
Customer 1 - Order 1
Customer 1 - Order 5
Customer 2 - Order 2
Customer 2 - Order 3
Customer 2 - Order 36
Dim results = From Customers In db.Customers
Join OrderCustomer In db.OrderCustomer on Customers.ID Equals OrderCustomer.CustomerId
Group Join Orders In db_alt.Orders On OrderCustomer.orderId Equals Orders.Id
Into CustomerOrders = Group,
OrderTotal = Sum(aufträge.Order_Value)
Select Customers.Firstname, Customers.Firstname, CustomerOrders, OrderTotal, Customers.ID
If all your foreign keys are properly set up, LINQ to SQL or EF should see the properties and you can do your query like this:
var result = db.Customers.Include("Order") // EF
That should bring all customers and each of them will have a collection of orders
Or var result = db.Customers.Select(c=>new {Customer = c, Orders = c.Orders}

SQL Server CE - bad performance

I'm developing an application that uses a SQL Server CE database and I am having trouble with the performance of the queries. For example, a simple query that gets the customer's last order:
SELECT
Customer.Name, Orders.Amount AS LastOrderAmount
FROM
Customers
LEFT JOIN
Orders ON Orders.OrderId IN (SELECT TOP(1) OrderId
FROM Orders
WHERE CustomerId = Customer.CustomerId
ORDER BY OrderNum DESC)
This query is incredibly slow. With only 30 costumers and about 300 orders it takes almost 10 seconds to finish!
I'm querying using SqlCEDataAdapter. I also tried using SqlCeResultSet, but the difference is negligible. Also, I have an index on Orders.CustomerId (creating it didn't make much difference, though).
Now, I'm not expecting miracles from SQL Server CE, but this is just terrible. So, is there something I can do to improve performance or is it just THAT slow?
Try this:
SELECT cus.Name
, outerOrd.Amount AS LastOrderAmount
FROM Customers cus
LEFT JOIN Orders outerOrd on outerOrd.CustomerId = cus.CustomerId
WHERE not exists (SELECT *
FROM Orders innerOrd
WHERE innerOrd.CustomerId = cus.CustomerId
and innerOrd.OrderId > outerOrd.OrderId
)
Edited, probably this is better:
SELECT cus.Name
, ord.Amount AS LastOrderAmount
FROM Customers cus
LEFT JOIN Orders ord on ord.CustomerId = cus.CustomerId
WHERE ord.OrderId = (SELECT max(OrderId)
FROM Orders
WHERE CustomerId = cus.CustomerId
)

Categories

Resources