I am working on a query to get monthly attendance totals by department. i.e it will show present employees in each department based on attendance logs table where check_type = 'C-IN'
Table 1: checkin_out_log
Columns: emp_id, check_time, check_type (C-IN, C-OUT)
Table 2: department
Table 3: employee
Expected output is
Department | Total Staff | Date 1 | Date 2 | Date 3|......
finance | 60 | 50 | 55 | 48 |.....
Here is my query which is currently returning me total staff in each department,
SELECT
*
FROM
(SELECT
d.id, d.name AS Department, T.DateToCheck,
COUNT(e.id) AS staff
FROM
employee e
CROSS JOIN
(SELECT
CAST(DATEADD(DAY, number, #DateFrom) AS DATE)
FROM
master..spt_values
WHERE
type = 'P'
AND DATEADD(DAY, number, #DateFrom) <= #DateTo ) T (DateToCheck)
LEFT JOIN
department d ON d.id = e.department
WHERE
d.id = 7
GROUP BY
d.id, d.name, T.DateToCheck) T
PIVOT
(MAX(staff)
FOR DateToCheck IN ([2018-09-01],[2018-09-02],[2018-09-03],[2018-09-04],[2018-09-05],[2018-09-06],[2018-09-07],[2018-09-08],[2018-09-09],[2018-09-10],
[2018-09-11],[2018-09-12],[2018-09-13],[2018-09-14],[2018-09-15],[2018-09-16],[2018-09-17],[2018-09-18],[2018-09-19],[2018-09-20],[2018-09-21],[2018-09-22],[2018-09-23],
[2018-09-24],[2018-09-25],[2018-09-26],[2018-09-27],[2018-09-28],[2018-09-29],[2018-09-30])) P
;
Related
I have two table as defined below,
Table: Customer:
ID | Customer_Name |Sex (bit)
--------------------------
1 | John | men
2 | Mack |women
3 | Andy |women
Table: Log:
ID | Customer_ID| Date
--------------------------
1 | 1 | 2020-06-03
2 | 3 |2020-06-03
I want to write a query to select each name with Sex condition and count of all Log placed by each customer using JOIN. the result will be,
1 | 1
2 | 0
3 | 0
My query:
(SELECT Customer.ID, COUNT(Log.Customer_ID) as number
from
Customer
Left JOIN
Log
on
Customer.Sex=0 and
Customer.ID=Log.Customer_ID
and
Log.Date>='2020-06-13'
group by Customer.ID)
But its returning incorrect results. Please advise
Use conditional aggregation
SELECT Customer.ID, COUNT(case Customer.Sex when 0 then Log.Customer_ID end) as number
from
Customer
Left JOIN
Log
on
Customer.ID=Log.Customer_ID
and
Log.Date>='2020-06-13'
group by Customer.ID
If you need only men/women move the predicate to WHERE
select Customer.ID, COUNT(Log.Customer_ID) as number
from Customer
left join Log
on Customer.ID=Log.Customer_ID
and Log.Date>='2020-06-13'
where Customer.Sex = 0
group by Customer.ID
Can you show the results this query is returning?
I think left join isn't a good approach, I would try with inner join instead if you want to filter in on clause (or just use where).
(SELECT Customer.ID, COUNT(Log.Customer_ID) as number
from Customer
JOIN Log on Customer.Sex=0 and Customer.ID=Log.Customer_ID and Log.Date>='2020-06-13'
group by Customer.ID)
I want to get the Catalog of a selected supplier along with the last purchase price which is the column Costs in the CommandDetails table as shown bellow :
Product (idproduct, productName)
Command (idCommand, CommandCode, CommandDate, idSupplier)
CommandDetails(idCommandDetails, idProduct, Qty, idCommand, Costs)
Supplier (idSupplier, SupplierName, SupplierAddress)
SupplierCatalog (idSupplier, idProduct)
I tried the row_number() Over (Partition by ...) and other methods but i'm missing something, my brain said enough.
Desired Result :
--------------------------------------------------
| SupplierName| ProductName | CommandDate | Costs|
--------------------------------------------------
| SUP1 | P1 | 01/01/2018 | 3,06 |
| SUP1 | P6 | 01/01/2018 | 1,65 |
| SUP1 | P8 | 03/01/2018 | 5,20 |
| SUP1 | P9 | 05/01/2018 | 8,00 |
| SUP1 | P10 | 01/01/2018 | NULL |
--------------------------------------------------
Null in Costs for P10 when the product has never been ordered.
My last attempt :
SELECT
*
FROM
(SELECT
Sct.idsupplier,
SCt.idProduct,
SCD.PurchasePriceCmd Costs,
SCD.Qty,
P.ProCode,
P.ProName,
Row_number() OVER(PARTITION BY Sct.idProduct order by P.ProCode) rn
FROM SupplierCatalog SCt
LEFT JOIN CommandDetails SCD
ON SCD.idProduct = SCat.idProduct
LEFT JOIN Command a
ON a.idCommand = SCD.idCommand
LEFT OUTER JOIN StoreCommand b
ON a.idCommand = b.idCommand
INNER JOIN Product P
ON P.idProduct = SCt.idProduct) t
where Sct.idSupplier = 4 and rn = 1
You could also try this:
SELECT
s.supplierName,
p.productName,
latestCommandDetail.CommandDate,
latestCommandDetail.Costs
FROM Supplier s
INNER JOIN SupplierCatalog sc ON sc.idSupplier = s.idSupplier
INNER JOIN Product p ON p.idProduct = sc.idProduct
OUTER APPLY
(
SELECT TOP 1
c.CommandDate,
cd.Costs
FROM Command c
INNER JOIN CommandDetails cd ON cd.idCommand = c.idCommand
WHERE c.idSupplier = s.idSupplier AND cd.idProduct = p.idProduct
ORDER BY c.CommandDate DESC
) latestCommandDetail
WHERE s.idSupplier = 4
ORDER BY
s.supplierName,
p.productName
I don't have SQL Server going on this machine at the moment so you may need to tweak the syntax. The trick is just doing a link to a subquery that returns the top row sorted by the date descending.
I'm assuming the idSupplier for "SUP1" is 4 as per you example code above.
OUTER APPLY (the other optional join) will return nulls if no record is returned from the sub query. If you are only interested in products with prices use CROSS APPLY instead.
Also note that this query does not determine what to do if:
- there are two Commands for the same last date from the same supplier for the same product but with different Costs
- the same product is sold twice under the same Command but at different Costs
In both cases this can probably be handled by extending the sort order of the sub-query or by grouping/aggregating the sub-query.
Something like this ought to work:
;with cte as (
select a.idCommand, b.idProduct, row_number() over (partition by b.idProduct
order by a.CommandDate desc) as rn, a.CommandDate, b.Costs
from Command a
inner join CommandDetails b on a.idCommand = b.idCommand
)
select
c.SupplierName, e.productName, cte.CommandDate, cte.Costs
from Supplier c
left join SupplierCatalog d on c.idSupplier = d.idSupplier
left join Product e on d.idProduct = e.idproduct
left join cte on e.idProduct = cte.idproduct and cte.rn = 1
where c.idSupplier = #SupplierNumber;
You can probably replace the common table expression at the top with a subquery, or take some fields out of the CTE and join them in later.
I have the following table structure also I have mention my expected output please help me with query as I don't know much about SQL query
Query :
SELECT * FROM(
SELECT ESIDispensary,ESILocation,test,Category, COUNT(*) AS [Total Count]
FROM
(SELECT category,ESILOCATION,ESIDISPENSARY,TEST
FROM(SELECT id,CompanyId,FName,Code,category,ESILOCATION,ESIDISPENSARY
FROM dbo.[EmployeeDetail] e WHERE e.CompanyId = 1 AND Category in (1,2)) a
LEFT JOIN
(SELECT *
from
(SELECT EmployeeId, CustomeFieldName,FieldValue
FROM dbo.[CustomeFieldDetail] C
JOIN dbo.[EmployeeDetail] e ON e.id = c.employeeid AND e.CompanyId = c.companyid
WHERE e.CompanyId = 1 AND Category IN (1,2)) SRC
PIVOT
(MAX(FieldValue) FOR CustomeFieldName IN([TEST]))
piv)
b ON a.Id = b.EmployeeId
) AS a
GROUP BY ESIDispensary ,ESILocation,test,Category) x
Table generated using above query
ESIDispensary ESILocation test Category Count
12 11 NULL 1 NULL
12 13 30 1 1
14 13 29 2 2
Table 1 : ESI
Id CompanyId FieldName ComboValue
11 1 ESILOCATION mumbai
12 1 ESIDISPENSARY mumbai
13 1 ESILOCATION pune
14 1 ESIDISPENSARY pune
29 1 TEST HDFC
30 1 TEST ICICI
Table 2 : Category
id CategoryName
1 staff
2 manager
Problem is i want to replace IDs with respected values also can i change above query to get expected result
Expected Summary Output :
ESIDispensary ESILocation test staff manager
mumbai mumbai NULL 1 NULL
mumbai pune ICICI 1 1
pune pune HDFC NULL 2
Is this is what you want:
SELECT (SELECT ComboValue FROM ESI WHERE ID = ESIDispensary) AS ESIDispensary,
SELECT ComboValue FROM ESI WHERE ID = ESILocation) AS ESILocation,
SELECT ComboValue FROM ESI WHERE ID = test) AS test,
Category, [Total Count]
FROM
(
SELECT ESIDispensary,ESILocation,test,Category, COUNT(*) AS [Total Count]
FROM
(SELECT category,ESILOCATION,ESIDISPENSARY,TEST
FROM(SELECT id,CompanyId,FName,Code,category,ESILOCATION,ESIDISPENSARY
FROM dbo.[EmployeeDetail] e WHERE e.CompanyId = 1 AND Category in (1,2)) a
LEFT JOIN
(SELECT *
from
(SELECT EmployeeId, CustomeFieldName,FieldValue
FROM dbo.[CustomeFieldDetail] C
JOIN dbo.[EmployeeDetail] e ON e.id = c.employeeid AND e.CompanyId = c.companyid
WHERE e.CompanyId = 1 AND Category IN (1,2)) SRC
PIVOT
(MAX(FieldValue) FOR CustomeFieldName IN([TEST]))
piv)
b ON a.Id = b.EmployeeId
) AS a
GROUP BY ESIDispensary, ESILocation, test, Category) x
I have a table with "customer_id, date, installment_no, amount" columns. I want to get the information of last installment of each customer_id till today. here installment_no is int type and when a new installment is deposited, the installment_no is increased by 1 in new entry. My table look like:
CS1001 | 12-06-2013 | 1 | 2500
CS1002 | 19-06-2013 | 1 | 1600
CS1001 | 14-07-2013 | 2 | 2500
I want to get a sqlcommand statement for do so.
Group all records by customer_id, then order all customer's records by installment_no, and select only record with max installment_no from each group:
from c in customers
group c by c.customer_id into g
select g.OrderByDescending(x => x.installment_no).First()
Same with pure SQL if you don't use Linq
SELECT c.* FROM Customers c
INNER JOIN (
SELECT customer_id, MAX(installment_no) max_installment
FROM Customers
GROUP BY customer_id
) cmax
ON c.customer_id = cmax.customer_id
AND c.installment_no = cmax.max_installment
var result = list.GroupBy(x=>x.customer_id)
.Select(g=>g.OrderByDescending(y=>y.installment_no).First())
.ToList();
I am developing c# application.
I am using OLEDB connections.
I have following two tables>>
payment
AdmissionNumber | StudName |
1 John
2 Smith
paymentDetails
AdmissionNumber | RemainingFee | Date | Payment
1 5000 10/10/2012 3000
1 3000 10/11/2012 2000
2 4000 15/11/2012 3000
1 1000 10/12/2012 2000
In this I want to get the table result as following>>
AdmissionNumber | Name | Date |RemainingPayment|Payment|
1 John 10/12/2012 1000 2000
In this case Admission number and date is already provided in the form via textbox and datetimepicker.
In this case Admission number and date is already provided in the form
via textbox and datetimepicker.
So you want to search for a specific Admission number and a date. If so, then try this:
SELECT
p.AdmissionNumber,
p.Name,
pd.Date,
pd.RemaingFee AS RemainingPayment,
pd.Payment
FROM Payment p
INNER JOIN PaymentDetails pd ON p.AdmissionNumber = pd.AdmissionNumber
WHERE p.AdmissionNumber = #AdmissionNumberParamFromTxtBox
AND pd.Date = #DateParamFromTheotherTextBox;
This will give you the exact result. Matching between master and the last record of the details. You should have an Primary key column in the details.
Select *
From Payment
Left Outer Join
PaymentDetail
On PaymentDetail.Id = (
Select Top 1
A.Id
From PaymentDetail As A
Where A.AdmissionNumber = Payment.AdmissionNumber
Order By A.Date Desc
)
Cheers
SELECT
p.AdmissionNumber,
p.Name,
MAX(pd.Date) AS Date,
pd.RemaingFee AS RemainingPayment,
pd.Payment
FROM Payment p
INNER JOIN PaymentDetails pd ON p.AdmissionNumber = pd.AdmissionNumber
GROUP BY p.AdmissionNumber,pd.Payment,p.Name,pd.RemaingFee