i have two tables .. one is a master table and other one is an daily report table.
Master table :
machine_id Machinename
1 abc
2 def
3 ghi
4 jkl
ven_fullreportmaster :
entry_date machine_id description_id tot_time shift_id
20110613 1 1 10 1
20110613 2 2 9 2
20110614 1 1 10 1
20110614 1 2 9 2
20110614 3 3 5 3
20110614 2 4 10 1
20110614 2 1 9 2
20110614 2 5 5 3
now, i want to retrieve the data from the daily report table that it should contain all the machine names with tot_time and entry_date..
i have used this query to retrieve the data,
select entry_date,
machinename,
(IsNull(cast(TotalMins / 60 as varchar(24)),'0') + ':' + IsNull(cast(TotalMins % 60 as varchar(24)),'0')) as TotalHrs--, shift_type
from (
select vm.machinename , vfrm.entry_date,
sum(case when vfrm.description_id in ('1','2','3','4','5') then DateDiff(mi, 0, total_time) else '0' end) as TotalMins
--vsm.shift_type
from ven_fullreportmaster vfrm
inner join ven_machinemaster vm on vm.machine_id = vfrm.machine_id
inner join ven_shifttypemaster vsm on vsm.shift_id = vfrm.shift_id
where vfrm.entry_date = '20110614'
-- and vfrm.shift_id in (1,2,3)
group by machinename, vfrm.entry_date --, vsm.shift_type
) as SubQueryALias group by entry_date, machinename,TotalMins --,shift_type
when i run the above query, i am getting details for machine-id 1 , 2,3 alone..
output:
entry_date machineid TotalHrs
2011-06-14 00:00:00.000 1 19:0
2011-06-14 00:00:00.000 2 24:0
2011-06-14 00:00:00.000 3 5:0
i need to get machine_id =4 value as 0 in TotalMins for each shift.. how to resolve it..plz help me ..
expected output:
entry_date machineid TotalHrs
2011-06-14 00:00:00.000 1 19:0
2011-06-14 00:00:00.000 2 24:0
2011-06-14 00:00:00.000 3 5:0
**2011-06-14 00:00:00.000 4 0:0**
thanks and regards
T.Navin
output:
Try using left joins instead of inner joins, that should get machine #3 to appear even though it has no entries in the second table.
You are searching for records with a specific date but there is no entry for 20110614 in your reporting table.
One solution is to add records to your select using a UNION with an initial SUM of'0'.
These fake records will not throw off your existing SUM.
They will show up where there's missing data with '0'.
SQL Statement
SELECT entry_date
, machinename
, (ISNULL(CAST(TotalMins / 60 AS VARCHAR(24)),'0') + ':' + ISNULL(CAST(TotalMins % 60 AS VARCHAR(24)),'0')) AS TotalHrs--, shift_type
FROM (
SELECT vm.machinename
, vfrm.entry_date
, SUM(case when vfrm.description_id in ('1','2','3','4','5') THEN DATEDIFF(mi, 0, total_time) else '0' END) AS TotalMins --vsm.shift_type
FROM ven_fullreportmaster vfrm
INNER JOIN ven_machinemaster vm on vm.machine_id = vfrm.machine_id
INNER JOIN ven_shifttypemaster vsm on vsm.shift_id = vfrm.shift_id
WHERE vfrm.entry_date BETWEEN '20110614' AND '20110615'
GROUP BY
machinename
, vfrm.entry_date --, vsm.shift_type
UNION ALL
SELECT DISTINCT vm.machinename
, vfrm.entry_date
, '0'
FROM ven_machinemaster vm
CROSS APPLY ven_fullreportmaster vfrm
WHERE vfrm.entry_date BETWEEN '20110614' AND '20110615'
) AS SubQueryALias
GROUP BY
entry_date
, machinename
, TotalMins --,shift_type
Instead of:
from ven_fullreportmaster vfrm
inner join ven_machinemaster vm on vm.machine_id = vfrm.machine_id
inner join ven_shifttypemaster vsm on vsm.shift_id = vfrm.shift_id
where vfrm.entry_date = '20110614'
can you try this LEFT JOIN ? Note the moving of the condition from WHERE to the ON clause:
FROM ven_machinemaster vm
LEFT JOIN ven_fullreportmaster vfrm
ON vm.machine_id = vfrm.machine_id
AND vfrm.entry_date = '20110614'
INNER JOIN ven_shifttypemaster vsm
ON vsm.shift_id = vfrm.shift_id
or:
FROM ven_machinemaster vm
LEFT JOIN ven_fullreportmaster vfrm
ON vm.machine_id = vfrm.machine_id
AND vfrm.entry_date = '20110614'
LEFT JOIN ven_shifttypemaster vsm
ON vsm.shift_id = vfrm.shift_id
Related
I have two tables.
Table1 has following data
Id1 Name Comments
--------------------
1 abc hgdhg
2 xyz mnoph
3 ysdfr jkljk
4 asdf iiuoo
5 pqrs liuoo
Table2 has following data
Id2 Id1 count date
-------------------------------
1 1 18 11/16/2005
2 1 1 11/15/2005
3 1 4 11/25/2005
4 2 4 11/22/2005
5 3 8 11/05/2005
6 3 3 11/30/2005
7 4 2 11/29/2005
8 3 0 11/04/2005
9 2 5 11/02/2005
10 3 9 11/22/2005
11 2 15 11/10/2005
12 5 12 11/19/2005
I want to return output as name, comments, sum of all count since 11/10/2005
I am trying the following query(with out date where condition)
select
Name, Comments, sum(count)
from
Table1 T1
join
Table2 T2 on T1.Id1 = T2.Id1
group by
ID1
But it is throwing error
Name is invalid in the select list because it is not contained in either an aggregate function or the Group by clause.
Can anyone help me with query (with the date where condition)? What's wrong with this?
Thanks in advance
You have to add any columns not contained in the aggregate function, and use where to filter the results:
select Name,
Comments,
sum(count)
from Table1 T1 join Table2 T2 on T1.Id1 = T2.Id1
where T2.[date] >= '11/10/2005'
group by Name, Comments
you can use below query
SELECT T1.Name ,
T1.Comments ,
SUM(T2.[count]) AS [count]
FROM Table1 T1
INNER JOIN Table2 T2 ON T1.Id1 = T2.Id1
WHERE CAST(T2.[date] AS DATE) >= CAST('11/10/2005' AS DATE)
GROUP BY T1.Name ,
T1.Comments
Every column in a select statement without an aggregate function needs to be in the group by sentence too to prevent aggregate errors, about limiting the date, use where clause to define the condition, like shows ahead.
select
Name, Comments, sum(count)
from
Table1 T1
join
Table2 T2 on T1.Id1 = T2.Id1
where
date >= '2005-11-10 00:00:00'
group by
Name, Comments
How can I write a SQL statement to select distinct data from three tables?
There are three tables
1)
Registration
id name contact
123 abc 123456789
2) bookingReg
PkBkID FkRegID ac_no
1 123 QT123
3) products
PkPro FkBkID pro_name Qty price
1 1 abc 2 150
2 1 def 1 400
3 1 ghi 5 500
4 1 abc 2 150
SELECT * FROM Registration as a
JOIN bookingReg as b ON (b.FkRegID = '123')
JOIN products as c ON (c.FkBkID = b.PkBkID )
I want distinct pro_name
Out put is
ac_no qty price
QT123 8 1050
HOw ?
Answer based on my assumption
SELECT pro_name,
ac_no,
SUM(qty) Sumqty,
SUM(price) SumPrice
FROM Registration a
JOIN bookingReg b
ON b.FkRegID = a.id
JOIN products c
ON c.FkBkID = b.PkBkID
GROUP BY pro_name, ac_no
EDIT Remove ac_no from SELECT and GROUP BY if you don't want to see this field in result.
Pls try this
SELECT A.ac_no, SUM(A.Qty) Qty, SUM(A.Price) Price
FROM
(
SELECT DISTINCT B.ac_no, P.Qty, P.Price
FROM Registration R
INNER JOIN bookingReg B ON B.FkRegID = R.id
INNER JOIN products P ON P.FkBkID = B.PkBkID
) A
GROUP BY A.ac_no
I was hoping someone could help me.
I have the following 5 tables:
tblCustomer
CustomerID CustomerName
------- ------------
1 ABC Bank
2 Chase Bank
tblOrderType
OrderTypeID OrderTypeName
---------- ------------
1 Assignment
2 LienRelease
tblActivity
ActivityID ActivityName
---------- ------------
1 Received
2 Keyed
3 Printed
4 Delivered To Cusotmer
tblOrder
OrderID CustomerID OrderTypeID LoanNumber
---------- ------------ ----------- ----------
1 1 1 45584565
2 1 1 45566856
3 1 1 45565584
4 1 1 45588545
tblOrderActivity
OrderID ActivityID ActivityDate
---------- ----------- ----------
1 1 2007-04-16 8:34:00 AM
1 2 2007-04-16 9:22:00 AM
1 3 2007-04-16 9:51:00 AM
1 4 2007-04-16 4:14:00 PM
2 1 2007-04-16 8:34:00 AM
3 1 2007-04-16 8:34:00 AM
3 2 2007-04-16 9:22:00 AM
3 3 2007-04-16 9:51:00 AM
3 4 2007-04-16 4:14:00 PM
4 1 2007-04-16 8:34:00 AM
4 2 2007-04-16 9:22:00 AM
4 3 2007-04-16 9:51:00 AM
The information has been changed for protection purposes. So say I need to be able to list all Assignment orders that have a “Received” activity but not a “Delivered” activity for ABC Bank and I need to return CustomerName, CustomerID, LoanNumber, and “received date” (Activity Date for received). I have been able to get everything done, however, I am unable to remove any files that have not had an Activity of "Delivered". Here is what I have so far:
SELECT tblCustomer.CustomerName, tblCustomer.CustomerID, tblOrder.LoanNumber, (tblOrderActivity.ActivityDate) AS [received date]
FROM tblOrderActivity (NOLOCK)
INNER JOIN tblOrder (NOLOCK)
ON tblOrderActivity.OrderID = tblOrder.OrderID
INNER JOIN tblCustomer (NOLOCK)
ON tblOrder.CustomerID = tblCustomer.CustomerID
INNER JOIN tblOrderType (NOLOCK)
ON tblOrder.OrderTypeID = tblOrderType.OrderTypeID
INNER JOIN tblActivity (NOLOCK)
ON tblActivity.ActivityID = tblOrderActivity.ActivityID
WHERE tblOrderType.OrderTypeName = 'Assignment'
AND EXISTS (SELECT DISTINCT [OrderID] FROM [tblOrderActivity] WHERE tblActivity.ActivityName = 'Received')
AND NOT EXISTS (SELECT DISTINCT [OrderID] FROM [tblOrderActivity] WHERE tblActivity.ActivityName = 'Delivered To Customer')
GROUP BY tblCustomer.CustomerName, tblCustomer.CustomerID, tblOrder.LoanNumber, tblOrderActivity.ActivityDate;
And my results are below
CustomerName CustomerID LoanNumber received date
---------- ------------ ----------- ----------
ABC Bank 1 45565584 2007-04-16 08:34:00.000
ABC Bank 1 45566856 2007-04-16 08:34:00.000
ABC Bank 1 45584565 2007-04-16 08:34:00.000
ABC Bank 1 45588545 2007-04-16 08:34:00.000
Try this. Not the most efficient t-sql in the world, but the schema doesn't help much. May need to alias the tables in the main query to make it more readable and ensure the subqueries work properly (at least that's what I usually do).
This should return all received records that do not have a delivery
SELECT tblCustomer.CustomerName, tblCustomer.CustomerID, tblOrder.LoanNumber, (tblOrderActivity.ActivityDate) AS [received date]
FROM tblOrderActivity (NOLOCK)
INNER JOIN tblOrder (NOLOCK)
ON tblOrderActivity.OrderID = tblOrder.OrderID
INNER JOIN tblCustomer (NOLOCK)
ON tblOrder.CustomerID = tblCustomer.CustomerID
INNER JOIN tblOrderType (NOLOCK)
ON tblOrder.OrderTypeID = tblOrderType.OrderTypeID
INNER JOIN tblActivity (NOLOCK)
ON tblActivity.ActivityID = tblOrderActivity.ActivityID
WHERE tblOrderType.OrderTypeName = 'Assignment'
AND NOT EXISTS (SELECT 1 FROM [tblOrderActivity] WHERE OA.ActivityID = 4 AND OA.OrderID = tblOrder.OrderID) --Delivered Excluded
AND tblOrderActivity.ActivityID = 1 --Received Only
Here is how I would do the query
SELECT *
FROM tblOrder
LEFT JOIN (
SELECT 'r' AS r, tblOrderActivity.ActivityDate, tblActivity.ActivityName, tblOrderActivity.OrderID
FROM tblOrderActivity
JOIN tblActivity ON tblOrderActivity.ActivityID = tblActivity.ActivityID
AND tblActivity.ActivityName = 'Received'
) AS Received ON tblOrder.OrderID = Received.OrderID
LEFT JOIN (
SELECT 'd' AS d, tblOrderActivity.ActivityDate, tblActivity.ActivityName, tblOrderActivity.OrderID
FROM tblOrderActivity
JOIN tblActivity ON tblOrderActivity.ActivityID = tblActivity.ActivityID
AND tblActivity.ActivityName = 'Delivered To Cusotmer'
) AS Delivered ON tblOrder.OrderID = Delivered.OrderID
WHERE Delivered.ActivityDate IS NULL
or like this
SELECT *
FROM tblOrder
LEFT JOIN (
SELECT 'r' AS r, tblOrderActivity.ActivityDate, tblActivity.ActivityName, tblOrderActivity.OrderID
FROM tblOrderActivity
JOIN tblActivity ON tblOrderActivity.ActivityID = tblActivity.ActivityID
AND tblActivity.ActivityID IN (SELECT ActivityID FROM tblActivity WHERE tblActivity.ActivityName = 'Received')
) AS Received ON tblOrder.OrderID = Received.OrderID
LEFT JOIN (
SELECT 'd' AS d, tblOrderActivity.ActivityDate, tblActivity.ActivityName, tblOrderActivity.OrderID
FROM tblOrderActivity
JOIN tblActivity ON tblOrderActivity.ActivityID = tblActivity.ActivityID
AND tblActivity.ActivityID IN (SELECT ActivityID FROM tblActivity WHERE tblActivity.ActivityName = 'Delivered To Cusotmer')
) AS Delivered ON tblOrder.OrderID = Delivered.OrderID
WHERE Delivered.ActivityDate IS NULL
trim it down to just the columns you want of course
I Have Table NEW:
Customer Date Id
1 201401 9
1 201401 1
1 201402 2
2 201404 3
2 201404 4
3 201406 5
4 201408 6
And table OLD:
Customer Date Id
1 201401 1
1 201402 2
2 201404 3
2 201404 4
3 201406 5
4 201408 6
Table NEW has all values from table OLD plus some new ones that are not in table OLD.
I need to find Customer that has same Key (column Customer) and same Date (Date) in both tables (OLD and NEW) and different ID in those tables.
So the SELECT should return in this case only
1 201401 9
I tried simple join :
SELECT *
FROM NEW n
LEFT JOIN OLD o ON n.ID = o.ID
WHERE n.Date = o.Date
AND n.ID <> o.ID
but its obviously wrong because of the condition for the join. But I can't join it on Customer so how can i do it some other way?
Thank you
You could use EXISTS/NOT EXISTS:
SELECT n.*
FROM NEW n
WHERE EXISTS(
SELECT 1 FROM Old o
WHERE n.Customer = o.Customer AND n.Date = o.Date
AND n.ID <> o.ID
)
AND NOT EXISTS(
SELECT 1 FROM Old o
WHERE n.Customer = o.Customer AND n.Date = o.Date
AND n.ID = o.ID
)
Demo
I have a ballot where each voter gets 3 votes, choosing from 10 different candidates. Vote 1 is allocated 3 points, vote 2 gets 2 points and vote 3 gets 1 point.
I have the following SQL queries to total the number of points gained from each of the votes (so separate results for votes 1, 2 and 3).
What I need to do is put all these results together in a single table, but I'm not too sure where to start.
SELECT cn.cand_name, (count(vote_1) * 3) as vote_1 FROM candidate_votes cv Inner Join candidate_names cn ON cv.vote_1 = cn.cand_number GROUP BY cand_name;
SELECT cn.cand_name, (count(vote_2) * 2) as vote_2 FROM candidate_votes cv Inner Join candidate_names cn ON cv.vote_2 = cn.cand_number GROUP BY cand_name;
SELECT cn.cand_name, (count(vote_3) * 1) as vote_3 FROM candidate_votes cv Inner Join candidate_names cn ON cv.vote_3 = cn.cand_number GROUP BY cand_name;
I have the following results table:
Voter_number Vote_1 Vote2 Vote3
123 cand_1 cand_3 cand_2
456 cand_2 cand_1 cand_3
789 cand_2 cand_3 cand_1
And the following candidate name table:
cand_number cand_name
cand_1 Dave
cand_2 Sarah
cand_3 Nigel
So the results I'm looking for will look something like:
Candidate Votes
Dave 6
Sarah 7
Nigel 5
SELECT
cn.cand_name,
count(cv1.vote_1) * 3 as vote_1,
count(cv2.vote_2) * 2 as vote_2,
count(cv3.vote_3) as vote_3
FROM
candidate_names cn
LEFT JOIN
candidate_votes cv1 ON cv1.vote_1 = cn.cand_number
LEFT JOIN
candidate_votes cv2 ON cv2.vote_2 = cn.cand_number
LEFT JOIN
candidate_votes cv3 ON cv3.vote_3 = cn.cand_number
GROUP BY cn.cand_name;
This also allows you to add all votes
(count(cv1.vote_1) * 3) +
(count(cv2.vote_2) * 2) +
count(cv3.vote_3) as totalvotes
Edit: rows are being multiplied by the JOIN which is why it's wrong for cand2 and cand3
SELECT
cn.cand_name,
SUM(CASE WHEN cv.vote_1 = cn.cand_number THEN 3 ELSE 0 END) as vote_1,
SUM(CASE WHEN cv.vote_2 = cn.cand_number THEN 2 ELSE 0 END) as vote_2,
SUM(CASE WHEN cv.vote_3 = cn.cand_number THEN 1 ELSE 0 END) as vote_3
FROM
candidate_names cn
JOIN
candidate_votes cv ON cn.cand_number IN (cv.vote_1, cv.vote_2, cv.vote_3)
GROUP BY cn.cand_name;
SELECT cn.cand_name
, COALESCE(cv1.cnt_1,0)
, COALESCE(cv2.cnt_2,0)
, COALESCE(cv3.cnt_3,0)
, 3*COALESCE(cv1.cnt_1,0) + 2*COALESCE(cv2.cnt_2,0)
+ 1*COALESCE(cv3.cnt_3,0) AS total
FROM candidate_names AS cn
LEFT JOIN
( SELECT vote_1 AS vote
, COUNT(*) AS cnt_1
FROM candidate_votes cv
GROUP BY vote_1
) AS cv1
ON cv1.vote = cn.cand_number
LEFT JOIN
( SELECT vote_2 AS vote
, COUNT(*) AS cnt_2
FROM candidate_votes cv
GROUP BY vote_2
) AS cv2
ON cv2.vote = cn.cand_number
LEFT JOIN
( SELECT vote_3 AS vote
, COUNT(*) AS cnt_2
FROM candidate_votes cv
GROUP BY vote_3
) AS cv3
ON cv3.vote = cn.cand_number
SELECT
Candidate = n.cand_name,
Votes = SUM(s.vote_weight)
FROM (
SELECT
cand_number = CASE x.weight
WHEN 1 THEN Vote3
WHEN 2 THEN Vote2
WHEN 3 THEN Vote1
END,
vote_weight = x.weight
FROM candidate_votes v
CROSS JOIN (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) x (weight)
) s
INNER JOIN candidate_names n ON s.cand_number = n.cand_number
GROUP BY n.cand_name