Display Summary Result in SQL Server - sql

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
Table 1 : Category
Name CatId
A 1
B 2
C 3
Table 2 : Emp Details
FName Id Dob CatId
Pratik 1 1958-04-06 2
Praveen 3 1972-05-12 1
Nilesh 2 1990-12-12 2
So far I have tried to get all result with:
SELECT A.Code,A.EmpName,A.DOB,B.cname
FROM EMPMASTER A
JOIN CATMASTER B ON A.cCode = B.ccode AND A.Compcode = B.CompCode
WHERE A.compcode = 'C0001' AND month(A.DOB) >= 1
AND MONTH(A.DOB) <= 12 AND A.termflag='L'
ORDER BY A.DOB
But my problem is, I also want summary results to be displayed
Expected Summary Output :
Grouping No Of Employees
A 1
B 2
C 0

I think you can use LEFT JOIN, GROUP BY and COUNT as follows:
SELECT [Grouping] = c.Name,
[No Of Employees] = COUNT(e.ID)
FROM Category AS c
LEFT JOIN EmpDetails AS e
ON e.CatId = c.CatId
GROUP BY c.Name;

TRY THIS:
SELECT A.NAME,
(SELECT COUNT(*) FROM #EMP B WHERE A.CATID = B.CATID) AS COUNT
FROM #TEMP A

Related

Select one row that is a duplicate and also select the other rows that are not duplicates

here is my code
select i.RefNo,i.Premium,i.Description from (select d.Description,c.IsActiveRecord,c.RefNo,c.MovementID, c.Premium,ROW_NUMBER()
over(partition by c.premium order by c.refno) n from lif_mgm_t_contract c
inner join SDT_LJG_T_MovementDescription d with (nolock) on c.MovementID = d.MovementID ) i
where i.n = 1 and i.MovementID <> 0
so for instance
table
a
a
b
I want the query to return
a
b and not just a hope this makes sense --only a beginner
try using a group by clause
SELECT OrderNumber
FROM AccountOrder
group by OrderNumber
so if my table has the following order numbers
1
2
2
3
the query would return
1
2
3

How to exclude records with certain values in sql select

How do I only select the stores that don't have client 5?
StoreId ClientId
------- ---------
1 4
1 5
2 5
2 6
2 7
3 8
I'm trying something like this:
SELECT SC.StoreId FROM StoreClients
INNER JOIN StoreClients SC
ON StoreClients.StoreId = SC.StoreId
WHERE SC.ClientId = 5
GROUP BY StoreClients.StoreId
That seems to get me all the stores that have that client but I can't do the opposite because if I do <> 5 ill still get Store 1 and 2 which I don't want.
I'm basically trying to use this result in another query's EXISTS IN clause
One way:
SELECT DISTINCT sc.StoreId
FROM StoreClients sc
WHERE NOT EXISTS(
SELECT * FROM StoreClients sc2
WHERE sc2.StoreId = sc.StoreId AND sc2.ClientId = 5)
SELECT SC.StoreId
FROM StoreClients SC
WHERE SC.StoreId NOT IN (SELECT StoreId FROM StoreClients WHERE ClientId = 5)
In this way neither JOIN nor GROUP BY is necessary.
SELECT DISTINCT a.StoreID
FROM tableName a
LEFT JOIN tableName b
ON a.StoreID = b.StoreID AND b.ClientID = 5
WHERE b.StoreID IS NULL
SQLFiddle Demo
OUTPUT
╔═════════╗
║ STOREID ║
╠═════════╣
║ 3 ║
╚═════════╝
SELECT StoreId
FROM StoreClients
WHERE StoreId NOT IN (
SELECT StoreId
FROM StoreClients
Where ClientId=5
)
SQL Fiddle
You can use EXCEPT syntax, for example:
SELECT var FROM table1
EXCEPT
SELECT var FROM table2
<> will surely give you all values not equal to 5.
If you have more than one record in table it will give you all except 5.
If on the other hand you have only one, you will get surely one.
Give the table schema so that one can help you properly

Selecting max value from 2nd table in first table results

I have 2 tables as below-
Table I
ID DATE
1 05/11/12
2 23/11/12
3 29/11/12
4 04/10/12
5 20/11/12
And another table (IH) with the following info-
ID RECNO NOTE
1 1 Open
1 2 Update
1 3 Close
2 1 Open
2 2 Update
2 3 Hold
2 4 Close
3 1 Open
4 1 Open
4 2 Update
5 1 Open
I would like to output a result as shown below, displaying the Note field using the highest value of RecNo for each ID. So using the data above the output should be-
ID DATE NOTE
2 23/11/12 Close
3 29/11/12 Open
The code I have is-
SELECT I.ID, I.DATE, IH.NOTE FROM
I I, IH IH
JOIN (SELECT MAX([RECNO]) [RECNO] FROM
IH
GROUP BY RECNO) IH2 ON IH2.ID = IH.ID AND
IH2.[RECNO] = IH.[RECNO]
JOIN I I2 ON I2.ID = IH.ID WHERE
(I2.DATE>={TS ‘2012-11-22 00:00:002}) GROUP BY I2.ID
However when I execute the code I get-
Invalid Column Name 'RECNO'. Statement(s) could not be prepared.
How about this? Note, haven't tried it, I'm on my Mac at the moment.
SELECT I.ID, I.DATE, IH.NOTE
FROM I I
OUTER APPLY
(SELECT TOP 1 *
FROM IH
WHERE IH.ID = I.ID
ORDER BY RECNO DESC) IH
WHERE I.DATE >= '2012-11-22'
Your SQL is rather, uh, messy.
Assuming you are using SQL Server 2005 or greater, you can use the row_number() function, as follows:
SELECT I.ID, I.DATE, IH.NOTE
FROM I join
(select ih.*, ROW_NUMBER() over (PARTITION by id order by recno desc) as seqnum
from IH
) ih
on IH2.[RECNO] = IH.[RECNO] and seqnum = 1
WHERE I2.DATE>='2012-11-22 00:00:002'
This is assigning a sequence number in the IH table, for each id with the highest record number getting the value "1". The rest is just SQL.
Your original query is simply not correct syntactically, but I think this is what you want based on the description.
and another one
SELECT I.ID, I.DATE
,(Select TOP 1 IH.NOTE FROM IH where IH.ID=i.ID Order by Recno DESC) as Note
from I
WHERE
I.DATE>'20121122'
maybe this will help
SELECT a.ID, a.DATE, b.NOTE FROM a
inner join b on a.ID = b.ID
where b.recno in (select max(bb.recno)
from b as bb where bb.id = b.id)
http://sqlfiddle.com/#!3/fd141/2
If you don't mind the different identifiers, look at this solution:
select t1.MyID, t1.MyDate, y.Note
from t1
join
(
select MyID, max(RecNo) as RecNo
from t2
group by MyID
) x
on t1.MyID = x.MyID
left join
(
select *
from t2
) y
on t1.MyID = y.MyID
and x.RecNo = y.RecNo
where t1.MyDate >= '2012.11.22'
The complete solution is here: http://sqlfiddle.com/#!3/4ca09/3
Update: Oops, forgot to bring in the date in where clause. Updated SQL Fiddle and the query above.

Join 2 tables: one data table and one table of statut and get statut with no entrie

I have this query:
SELECT c.Show_Code, req.Statut_ID, COUNT(req.Statut_ID) 'Count'
FROM [Case] c
JOIN Request req ON req.Case_Number = c.Number
GROUP BY c.Show_Code, req.Statut_ID
The result is:
Show_Code Statut_ID Count
564900 2 1
568127 2 1
And I have this statut table (Ref_RequestStatut)
ID Name
1 Test
2 Test2
How can I get this result:
Show_Code Statut_ID Count
564900 1 0
564900 2 1
568127 1 0
568127 2 1
I want all the statut, even those which have no value?
Thank
If you are using SQL Server 2005 or later:
WITH counted AS (
SELECT c.Show_Code, req.Statut_ID, COUNT(req.Statut_ID) 'Count'
FROM [Case] c
JOIN Request req ON req.Case_Number = c.Number
GROUP BY c.Show_Code, req.Statut_ID
),
showcodes AS (
SELECT DISTINCT Show_Code
FROM counted
)
SELECT
s.Show_Code,
r.ID AS Statut_ID,
Count = ISNULL(c.Count, 0)
FROM showcodes s
CROSS JOIN Ref_RequestStatut r
LEFT JOIN counted c ON s.Show_Code = c.Show_Code AND r.ID = c.Statut_ID
ORDER BY
s.Show_Code,
r.ID

Using (IN operator) OR condition in Where clause as AND condition

Please look at following image, I have explained my requirements in the image.
alt text http://img30.imageshack.us/img30/5668/shippment.png
I can't use here WHERE UsageTypeid IN(1,2,3,4) because this will behave as an OR condition and fetch all records.
I just want those records, of first table, which are attached with all 4 ShipmentToID .
All others which are attached with 3 or less ShipmentToIDs are not needed in result set.
Thanks.
if (EntityId, UsageTypeId) is unique:
select s.PrimaryKeyField, s.ShipmentId from shipment s, item a
where s.PrimaryKeyField = a.EntityId and a.UsageTypeId in (1,2,3,4)
group by s.PrimaryKeyField, s.ShipmentId having count(*) = 4
otherwise, 4-way join for the 4 fields,
select distinct s.* from shipment s, item a, item b, item c, item d where
s.PrimaryKeyField = a.EntityId = b.EntityId = c.EntityId = d.EntityId and
a.UsageTypeId = 1 and b.UsageTypeId = 2 and c.UsageTypeId = 3 and
d.UsageTypeId = 4
you'll want appropriate index on (EntityId, UsageTypeId) so it doesn't hang...
If there will never be duplicates of the UsageTypeId-EntityId combo in the 2nd table, so you'll never see:
EntityUsageTypeId | EntityId | UsageTypeId
22685 | 4477 | 1
22687 | 4477 | 1
You can count matching EntityIds in that table.
WHERE (count(*) in <tablename> WHERE EntityId = 4477) = 4
DECLARE #numShippingMethods int;
SELECT #numShippingMethods = COUNT(*)
FROM shippedToTable;
SELECT tbl1.shipmentID, COUNT(UsageTypeId) as Usages
FROM tbl2 JOIN tbl1 ON tbl2.EntityId = tbl1.EntityId
GROUP BY tbl1.EntityID
HAVING COUNT(UsageTypeId) = #numShippingMethods
This way is preferred to the multiple join against same table method, as you can simply modify the IN clause and the COUNT without needing to add or subtract more tables to the query when your list of IDs changes:
select EntityId, ShipmentId
from (
select EntityId
from (
select EntityId
from EntityUsage eu
where UsageTypeId in (1,2,3,4)
group by EntityId, UsageTypeId
) b
group by EntityId
having count(*) = 4
) a
inner join Shipment s on a.EntityId = s.EntityId