how to check there is no dues in the following cte - sql-server

the CTE works awesomely but i don't know where to put put if condition if the sale is first
i want sum function works in that case if the their is more than 1 debit against each accountid
CREATE PROCEDURE [dbo].[counter_bills] #SDate date,
#enddate date
AS
BEGIN;
WITH
CUST AS
(SELECT customer.customername,
customer.customercontact,
customer.customeraddress,
account.account_id,
account.account_type,
customer.customerid
FROM account
JOIN customer ON customer.customerid = account.customerid),
journal AS
(SELECT SUM(journal_entry.debit) - SUM(journal_entry.credit) AS [dues],
journal_entry.account_id AS [journal account id]
FROM journal_entry
GROUP BY journal_entry.account_id),
SALES AS
(SELECT sale.saleid,
sale.totalpaid,
Stock.itemname AS item,
invoice.saleprice AS SalePrice,
invoice.qty,
invoice.StockID AS [invoice Stock id],
invoice.saleprice AS [invoice saleprice],
sale.date,
Stock.size,
sale.customerid AS [cust sale id ]
FROM invoice
JOIN Stock ON invoice.StockID = Stock.StockID
JOIN sale ON invoice.saleid = sale.saleid
JOIN Our_orders ON Stock.orderID = Our_orders.orderID
JOIN vendor ON Our_orders.VendorID = vendor.VendorID
WHERE sale.date BETWEEN #SDate AND #enddate)
SELECT *
FROM CUST
RIGHT JOIN SALES ON CUST.customerid = SALES.[cust sale id ]
LEFT JOIN journal ON journal.[journal account id] = CUST.account_id
ORDER BY SALES.SaleID DESC;
END;

Related

Top 5 Employees from each dept with lowest attendance

How do I find top 5 employees from each department with lowest attendance?
---Employee Table
--- Department Table
--- Attendance Table
I tried in this way to find top 5 salary from each department but how to apply in this specially for attendance table with employee and department table how to find top 5 employees with lowest attendance please assist me in this regard with cte.
Thanks
With ctetemp As
(
Select E.EmpId, E.Ename, E.Salary,D.Dname,
DENSE_RANK() OVER(PARTITION BY D.DeptId ORDER BY Salary desc) as rnw
from EmployeeTbl AS E JOIN Departmet AS D
ON D.DeptId = e.Dept_Id_Emp
)
Select * from ctetemp
where rnw IN (5)
You will need to reference the attendance table.
I'm assuming 'a' means 'absent' in this context.
SELECT
AbsenceSummary.DeptID
,AbsenceSummary.EmpId
,AbsenceSummary.AbsentDays
,AbsenceSummary.AbsentRank
FROM
(
SELECT
dept.DeptId
,att.EmpId
,COUNT(*) AS AbsentDays
,DENSE_RANK() OVER (PARTITION BY dept.DeptId ORDER BY COUNT(*) DESC) AS AbsentRank
FROM
attendance att
INNER JOIN
employee emp
ON emp.EmpID = att.EmpId
INNER JOIN
department dept
ON dpt.DeptId = emp.DeptId
WHERE
dept.DeptId IN (<the departments you care about>)
AND att.atdate >= <your minimum date>
AND att.atdate <= <your maximum date>
AND att.attendance = 'a' --absent
GROUP BY
dept.DeptId
,att.EmpId
) AbsenceSummary
WHERE
AbsenceSummary.AbsentRank <= 5
For the record, the AtId column in this situation is useless and possibly counterproductive. The key is (EmpId,atDate).

SQL Server : restricting data range

The query below is supposed to show details for 2 types of products: DIS001 and DIS002.
When DIS002, this should "reset" the query, so that it only shows DIS001 products which were sold after that the date when DIS002 was sold.
To be honest, I'm not even sure if this is possible. I'll be grateful for any suggestions.
SELECT DISTINCT
Sales.RaisedDateTime AS [Date],
Contacts.ContactID AS [Contact ID],
Contacts.SiteID AS [Site ID],
Sales.ProductID AS [Product],
CASE
WHEN Sales.ProductID = 'DIS002'
THEN Sales.RaisedDate
ELSE CONVERT(DATETIME, CONVERT(VARCHAR(10), '2019-10-28', 101) + ' 00:00:00')
END AS [Start Date]
FROM
((Bookings.Bookings Bookings
INNER JOIN
Contacts.Contacts Contacts ON (Bookings.ContactID = Contacts.ContactID))
INNER JOIN
Sales.Sales Sales ON (Bookings.ContactID = Sales.ContactID))
WHERE
(Sales.ProductID = 'DIS001' AND
Sales.RaisedDate >= MAX([Start Date])
There are lots of different syntax's to solve this, but here is one:
;with DIS002 as (
select ContactID, max(RaisedDate) as DIS002Date
from Sales.Sales
where ProductID = 'DIS002'
group by ContactID
)
SELECT DISTINCT
Sales.RaisedDateTime AS [Date],
Contacts.ContactID AS [Contact ID],
Contacts.SiteID AS [Site ID],
Sales.ProductID AS [Product]
FROM
((Bookings.Bookings Bookings
INNER JOIN
Contacts.Contacts Contacts ON (Bookings.ContactID = Contacts.ContactID))
INNER JOIN
Sales.Sales Sales ON (Bookings.ContactID = Sales.ContactID))
LEFT JOIN
DIS002 on DIS002.ContactID = Sales.ContactID
WHERE
Sales.ProductID = 'DIS001' AND
Sales.RaisedDate >= isnull(DIS002date,'1900-01-01')

create sql query to fetch repeat column values within time frame

Can someone help me with this query? I want to get the result of all the customer_id which repeats more than once in 24hrs
SELECT
O.Order_No, O.Customer_ID, O.DateOrdered, O.IPAddress,
C.FirstName, C.LastName, CD.nameoncard
FROM
Order_No O
INNER JOIN
CardData CD ON O.card_id = CD.id
INNER JOIN
Customers C ON O.customer_id = C.customer_id
ORDER BY
O.order_no desc
adding more details..
so suppose order with customer id xx was placed on 04/23 2:30 pm and again 2nd order was placed with same customer Id xx on same day 04/23 5:30 pm.
i want the query to return me customer Id xx
Thanks
select Customer_ID, CAST(DateOrdered as Date) DateOrdered, count(*) QTDE
from Order_No
group by Customer_ID, CAST(DateOrdered as Date)
having count(*) > 1
To get the customers who have orders issued after the first one, then you could use the following query:
select distinct A.Customer_ID
from Order_No A
inner join (select Customer_ID, min(DateOrdered) DateOrdered from Order_No group by Customer_ID ) B
on A.Customer_ID = B.Customer_ID
and A.DateOrdered - B.DateOrdered <= 1
and A.DateOrdered > B.DateOrdered
SQL Fiddle
To get all customers that have ANY TIME more than one order issued in period less or equal than 24h
select distinct A.Customer_ID
from Order_No A
inner join Order_No B
on A.Customer_ID = B.Customer_ID
and A.DateOrdered > B.DateOrdered
and A.DateOrdered - B.DateOrdered <= 1
SQL Fiddle
Self-join:
SELECT distinct O.Customer_ID
FROM
Order_No O
inner join Order_No o2
on o.customerID = o2.customerID
and datediff(hour, o.DateOrdered, o2.DateOrdered) between 0 and 24
and o.Order_No <> o2.Order_No
This will return all customer_IDs that have ever placed more than one order in any 24 hour period.
Edited to add the join criteria that the matching records should not be the same record. Should return customers who placed two different orders at the same time, but not customers who placed only one order.

SQL Group, get First purchase, Last Purchase and last employee associated with last purchase

In my DB I have Customers, who make Purchases, and those purchases are then associated with an employee who assisted with that purchase. I have written a query below that will provide me with a list of customers with how many total purchases they have made, their first purchase and the last purchase. I also want the employee name associated with the last purchase?
Customer
-cstId
-cstName
Purchase
-cstId
-soldDate
-empId
Employee
-FirstName
-LastName
-empId
SELECT customer.cstName, MAX(purchase.soldDate) AS [Last Purchase], MIN(purchase.soldDate) AS [First Purhcase], COUNT(invTruck.invId)
AS [Total Purchases]
FROM customer INNER JOIN
purchase ON customer.cstId = purchase.cstId
INNER JOIN
employee ON purchase.empId = employee.empId
GROUP BY customer.cstName
Can you use a stored procedure? I usually fall back to memory tables for situations like this.
Declare #tblCust TABLE (
cstid int null,
cstName varchar(50) null,
lastpurchase datetime null,
firstpurchase datetime null,
empid varchar(50) null
)
Insert into #tblCust(cstid, cstname, lastpurchase, firstpurchase)
SELECT purchase.cstid, customer.cstName, MAX(purchase.soldDate) AS [Last Purchase],
MIN(purchase.soldDate) AS [First Purhcase]
FROM customer INNER JOIN
purchase ON customer.cstId = purchase.cstId
GROUP BY purchase.cstId, customer.cstName
Update t set EmpId = p.EmpId
From #tblCust t
INNER JOIN Purchase p ON t.cstId = p.cstid and t.LastPurchase = p.soldDate
You now have the employee id on a temp table that you can return your data from, or join to any other tables you may need.
I'm assuming you have some primary key on purchase table. I named it "purchaseID":
SELECT customer.cstName,
MAX(purchase.soldDate) AS [Last Purchase],
MIN(purchase.soldDate) AS [First Purhcase],
COUNT(invTruck.invId) AS [Total Purchases],
LastPurchase.empID AS [Last Purchase Employee]
FROM customer INNER JOIN
purchase ON customer.cstId = purchase.cstId
INNER JOIN
employee ON purchase.empId = employee.empId
CROSS APPLY (
SELECT TOP 1 *
FROM purchase px
WHERE px.purchaseID = purchase.purchaseID
ORDER BY px.soldDate DESC) AS LastPurchase
GROUP BY customer.cstName,
LastPurchase.empID
What the CROSS APPLY does is runs the enclosed select statement on every record, utilizing the WHERE criteria also inside. It behaves similarly to an INNER JOIN relative to an OUTER APPLY which behaves similarly a LEFT JOIN.
you could use APPLY: http://msdn.microsoft.com/library/ms175156(v=sql.105).aspx
use cross apply to get the list of purchases and the respective employee, with TOP 1 and sort by soldDate desc
example:
CROSS APPLY (
select top 1 p.empId
from purchase p
where p.cstId = customer.cstId
order by soldDate desc
) o (emp)
and add o.emp to your select
i'm not 100% sure that the syntax is 100% perfect but the idea is there :P
You can just extend it with a simple SCALAR SUBQUERY
SELECT
customer.cstName,
MAX(purchase.soldDate) AS [Last Purchase],
MIN(purchase.soldDate) AS [First Purhcase],
COUNT(invTruck.invId) AS [Total Purchases],
(SELECT TOP(1) e.lastname
FROM purchase p
INNER JOIN employee e ON p.empId = e.empId
WHERE customer.cstId = p.cstId
ORDER BY p.soldDate DESC) lastPurchaseEmployee
FROM customer
INNER JOIN purchase
ON customer.cstId = purchase.cstId
INNER JOIN employee
ON purchase.empId = employee.empId
GROUP BY
customer.cstId, customer.cstName

SQL Server 2008 - Get Latest Record from Joined Table

I have a SQL Server 2008 database. This database has two tables called Customer and Order. These tables are defined as follows:
Customer
--------
ID,
First Name,
Last Name
Order
-----
ID,
CustomerID,
Date,
Description
I am trying to write a query that returns all of the customers in my database. If the user has placed at least one order, I want to return the information associated with the most recent order placed. Currently, I have the following:
SELECT
*
FROM
Customer c LEFT OUTER JOIN Order o ON c.[ID]=o.[CustomerID]
As you can imagine, this will return all of the orders associated with a customer. In reality though, I only want the most recent one. How do I do this in SQL?
Thank you!
Here's a method that doesn't assume that the order dates are unique:
SELECT
Customer.ID CustomerID,
Customer.FirstName,
Customer.LastName,
T1.ID OrderID,
T1.Date OrderDate,
T1.Description OrderDescription
FROM Customer
LEFT JOIN (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY CustomerId ORDER BY Date DESC) AS rn
FROM [Order]
) T1
ON Customer.ID = T1.CustomerID AND T1.rn = 1
Result:
CustomerID FirstName LastName OrderID OrderDate OrderDescription
1 FirstName1 LastName1 2 2010-05-02 Description2
2 FirstName2 LastName2 3 2010-05-03 Description3
3 FirstName3 LastName3 NULL NULL NULL
Test data:
CREATE TABLE Customer (ID INT NOT NULL, FirstName VARCHAR(100) NOT NULL, LastName VARCHAR(100) NOT NULL);
INSERT INTO Customer (ID, FirstName, LastName) VALUES
(1, 'FirstName1', 'LastName1'),
(2, 'FirstName2', 'LastName2'),
(3, 'FirstName3', 'LastName3');
CREATE TABLE [Order] (ID INT NOT NULL, CustomerID INT NOT NULL, Date DATE NOT NULL, Description NVARCHAR(100) NOT NULL);
INSERT INTO [Order] (ID, CustomerID, Date, Description) VALUES
(1, 1, '2010-05-01', 'Description1'),
(2, 1, '2010-05-02', 'Description2'),
(3, 2, '2010-05-03', 'Description3'),
(4, 2, '2010-05-03', 'Description4');
select c.ID, c.FirstName, c.LastName, o.ID as OrderID, o.Date, o.Description
from Customer c
left outer join (
select CustomerID, max(Date) as MaxDate
from Order
group by CustomerID
) om on c.ID = om.CustomerID
left outer join Order o on om.CustomerID = o.CustomerID and om.MaxDate = o.Date
I would use where clause with Max() function to guarantee the latest added record:
(you code...)
Where o.id = max(o.id)
Select * from
Customer C Left join
(
Select o.CustomerID, Description, Date from
Orders o inner join
(
Select CustomerID, Max(Date) as LastOrder
From Orders Group by CustomerID
) SubLatest on o.CustomerID = SubLatest.CustomerID
and o.Date = SubLatest.LastOrder
) SubDetails
on C.id = SubDetails.CustomerID
Not Homework I hope! :O)
Select Top 1 C.*
,O.*
From Customer C left outer join
Order O on O.CustomerId = C.Id
Order by O.[Date] Desc
Hope that helps

Resources