Problem in query in sql server 2008 - sql-server

I have a table called album with the following columns:
Album_Id, User_Id, Report_Id, PhotoName
There are different Photoname on a User_Id and Report_Id combination
Like:
Album_Id User_Id Report_Id PhotoName
1 1 16 A.jpg
2 1 16 B.jpg
3 2 17 C.jpg
4 2 17 D.jpg
I just want to retrieve data in format
User_Id Report_Id PhotoName1 PhotoName2
1 16 A.jpg B.jpg
2 17 C.jpg D.jpg
Max Photos are 4...

WITH cte
AS ( SELECT * ,
ROW_NUMBER() OVER ( PARTITION BY User_Id, Report_Id ORDER BY Album_Id ) AS RN
FROM T
)
SELECT User_Id ,
Report_Id ,
MAX(CASE WHEN RN = 1 THEN PhotoName
END) AS PhotoName1 ,
MAX(CASE WHEN RN = 2 THEN PhotoName
END) AS PhotoName2 ,
MAX(CASE WHEN RN = 3 THEN PhotoName
END) AS PhotoName3 ,
MAX(CASE WHEN RN = 4 THEN PhotoName
END) AS PhotoName4
FROM cte
GROUP BY User_Id ,
Report_Id

SELECT a.User_Id, a.Report_Id, a.PhotoName as 'PhotoName1', a2.PhotoName as 'PhotoName2', a3.PhotoName as 'PhotoName3', a4.PhotoName as 'PhotoName4'
FROM album a
LEFT JOIN album a2 on a2.User_Id = a.User_Id and a2.Report_Id = a.Report_Id AND a2.Album_Id != a.Album_Id
LEFT JOIN album a3 on a3.User_Id = a.User_Id and a3.Report_Id = a.Report_Id AND a3.Album_id NOT IN (a.Album_Id, a2.Album_Id)
LEFT JOIN album a4 on a4.User_Id = a.User_Id and a4.Report_Id = a.Report_Id AND a4.Album_id NOT IN (a.Album_Id, a2.Album_Id, a3.Album_Id)
ORDER BY a.User_Id, a.Report_Id ASC;

Related

Find min and max data from multiple columns

I have a table that specifies exactly what date and time each employee was in a particular office.I want to know on what date and time each employee arrived at work and on what date and time he left work. I also want to know how many times he has been at work in each time process.
EmployeeTable looks like this:
id
EmployeeID
DateP
TimeP
1
11111
1397/01/02
01:30
2
11111
1398/05/09
05:30
3
11111
1398/06/07
05:10
4
22222
1398/08/09
06:12
5
22222
1399/02/01
07:15
6
11111
1399/07/02
08:51
7
11111
1399/08/06
12:20
8
33333
1399/09/04
20:01
9
33333
1399/12/08
22:05
10
33333
1400/01/01
23:11
11
33333
1400/02/05
14:10
12
22222
1400/04/05
16:25
I want exactly select Min and Max date and time for each Employee when present in a office and how many times he/she has been present at work in each stage.:
id
EmployeeID
MinDateP
TimeMinDateP
MaxDateP
TimeMaxDateP
Count
1
11111
1397/01/02
01:30
1398/06/07
05:10
3
2
22222
1398/08/09
06:12
1399/02/01
07:15
2
3
11111
1399/07/02
08:51
1399/08/06
12:20
2
4
33333
1399/09/04
20:01
1400/02/05
14:10
4
5
22222
1400/04/05
16:25
1400/04/05
16:25
1
This is the SQL code that indicates exactly when each employee arrived at work and when he or she left work :
WITH cte AS
(
SELECT
*,
ROW_NUMBER() OVER (ORDER BY DateP, TimeP) rn1,
ROW_NUMBER() OVER (PARTITION BY EmployeeID ORDER BY DateP, TimeP) rn2
FROM
EmployeeTable
),
cte2 AS
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY EmployeeID, rn1 - rn2
ORDER BY DateP, TimeP) rn_first,
ROW_NUMBER() OVER (PARTITION BY EmployeeID, rn1 - rn2
ORDER BY DateP DESC, TimeP DESC) rn_last
FROM
cte
)
SELECT
EmployeeID,
MAX(CASE WHEN rn_first = 1 THEN DateP END) AS MinDateP,
MAX(CASE WHEN rn_first = 1 THEN TimeP END) AS TimeMinDateP,
MAX(CASE WHEN rn_last = 1 THEN DateP END) AS MaxDateP,
MAX(CASE WHEN rn_last = 1 THEN TimeP END ) AS TimeMaxDateP
FROM
cte2
GROUP BY
EmployeeID,
rn1 - rn2
ORDER BY
MIN(DateP), MIN(TimeP);
But I want to know how many times each employee has been at work at any given time (Count column)
Can anybody help me?
If I understand correctly, you just want to know the number of records in each employee island. In that case, just select COUNT(*) in your final query:
SELECT
EmployeeID,
MAX(CASE WHEN rn_first = 1 THEN DateP END) AS MinDateP,
MAX(CASE WHEN rn_first = 1 THEN TimeP END) AS TimeMinDateP,
MAX(CASE WHEN rn_last = 1 THEN DateP END) AS MaxDateP,
MAX(CASE WHEN rn_last = 1 THEN TimeP END) AS TimeMaxDateP,
COUNT(*) AS count
FROM cte2
GROUP BY
EmployeeID,
rn1 - rn2
ORDER BY
MIN(DateP),
MIN(TimeP);

How to pivot table from multiple column to multiple rows

CodeDt CodeHeader Item Qty Type Remark Attachment
LK4-033502 RK-K-LK4-032438 IA01001023 2.00 TPR002 2 1.jpeg
LK4-033502RK RK-K-LK4-032438 IA01001023RK 2.00 NULL IA01001023 NULL
Above is my data from Sql server table (using 2008 R2). I want to make it one row only. Here is my expected result:
CodeDt CodeHeader Item NewItem Qty
LK4-033502 RK-K-LK4-032438 IA01001023 IA01001023RK 2.00
How can I achieve that? Here is the relation:
Row 1 Item = Row 2 Remark,
Row 1 Code DT = Row 2 CodeDt+'RK'
There are several solutions
1) Using JOIN. It assumes that Type field is null for rows with CodeDt+'RK'
select
a.CodeDt, a.CodeHeader, a.Item, b.Item, a.Qty
from
myTable a
join myTable b on a.Item = b.Remark
where
a.Type is not null
2) Conditional aggregation
select
max(case when rn = 1 then CodeDt end)
, CodeHeader
, max(case when rn = 1 then Item end)
, max(case when rn = 2 then Item end)
, max(case when rn = 1 then Qty end)
from (
select
*, rn = row_number() over (partition by CodeHeader order by CodeDt)
from
myTable
) t
group by CodeHeader

how to compare two sql query values

I have two tables StockOutward and product outward..I have to fetch the sum(qty) that not equals to sum(qty) stockOutward..
StockOutward
Id ProductId Qty Location Orderid
1 7 2 2 38
2 8 1 2 38
3 7 1 2 38
ProductOutward
Id ProductId Qty Location Orderid
1 7 12 2 38
2 8 1 2 38
I need the output from stockoutward as ProductId 7
I have used the below query
Select
sum(qty) as Qty,ProductId
from
StockOutward
where
Orderid='38'
group by
ProductId
Union
Select
sum(qty) as Qty,
ProductId
from
ProductOutward
where
Orderid='38'
group by
ProductId
You could use JOIN and filter for inequality:
SELECT
s.ProductId
FROM (
SELECT
ProductId,
SumQty = SUM(Qty)
FROM StockOutward
GROUP BY ProductId
)s
INNER JOIN (
SELECT
ProductId,
SumQty = SUM(Qty)
FROM ProductOutward
GROUP BY ProductId
)p
ON p.ProductId = s.ProductId
AND p.SumQty <> s.SumQty
Select sum(qty) as Qty,ProductId from StockOutward where Orderid='38' group by ProductId
except
Select sum(qty) as Qty,ProductId from ProductOutward where Orderid='38' group by ProductId

Denormalize data for purchased items

I have the following table:
BoughtItems
UserID ItemID StoreID Quantity Price
1 1 1 1 1
1 4 1 2 3
1 5 2 1 3
Let's assume that it will be no more then five items for each user in BoughtItems table.
I want to have all the clients from some StoreID and all items that were purchased, in this format... for StoreID = 1 the result will be:
UserID Item1ID Item2ID Item3ID Item4ID Item5ID
1 1 4 [empty] [empty] [empty]
DECLARE #StoreID INT;
SET #StoreID = 1;
;WITH x AS
(
SELECT UserID, ItemID,
rn = ROW_NUMBER() OVER (PARTITION BY UserID ORDER BY ItemID)
FROM dbo.BoughtItems
WHERE StoreID = #StoreID
)
SELECT UserID,
Item1ID = MAX(CASE WHEN rn = 1 THEN ItemID END),
Item2ID = MAX(CASE WHEN rn = 2 THEN ItemID END),
Item3ID = MAX(CASE WHEN rn = 3 THEN ItemID END),
Item4ID = MAX(CASE WHEN rn = 4 THEN ItemID END),
Item5ID = MAX(CASE WHEN rn = 5 THEN ItemID END)
FROM x WHERE rn <= 5
GROUP BY UserID;

Combine two queries, which include aggregations, into a single query

Table "tblCustomer":
Customer_id
created
field1
field2
cardno
1014
2010-05-25 12:51:59.547
Cell Phone
abc#lmn.com
1234567890
1015
2010-08-15 12:51:59.547
Email
abc#xyz.com
2345678891
Table "tbl_TransactionDishout":
Trnx_id
offerNo
TerminalID
Created
VirtualCard
1
1014
170924690436418
2010-05-25 12:51:59.547
1234567890
Expected Output:
Enrolled
Enrolled as Email
Enrolled as Text
Deals Redeemed
<First Date>
7
5
2
6
<Next Date>
9
3
6
14
I have two different queries which I need to combine into one.
First One:
SELECT CAST(FLOOR(CAST(t.created AS FLOAT )) AS Datetime) created,
COUNT(field1) Enrolled,
COUNT(CASE field1 WHEN 'E-mail' THEN 1 END) Enrolled_as_Email,
COUNT(CASE field1 WHEN 'Cell Phone' THEN 1 END) Enrolled_as_Cell
FROM tblCustomer as t
GROUP BY t.created
ORDER BY t.created DESC
Which Displays:
create
Enrolled
Enrolled_as_Email
Enrolled_as_Cell
2012-03-01 00:00:00.000
3
1
2
2012-02-29 00:00:00.000
1
0
1
Second One:
SELECT CAST(FLOOR(CAST(t.created AS FLOAT)) AS Datetime) created,
COUNT(*) [Deals_Redeemed]
FROM tbl_TransactionDishout t
LEFT JOIN tblCustomer c
ON t.VirtualCard = c.cardno
GROUP BY CAST(FLOOR(CAST(t.created AS FLOAT )) as Datetime)
ORDER BY t.created desc
Which Displays:
create
Deals_Redeemed
2012-03-02 00:00:00.000
1
2012-03-01 00:00:00.000
6
2012-02-28 00:00:00.000
1
2012-02-27 00:00:00.000
2
Now I want a record which contain date from both and should be combined into one.
But It's giving me the result of the date contained only in tblCustomer table..
How to get "Deals_redeemed"?
Note: relation between tbl_transaction and tblCustomer is having same cardno.
SELECT
CAST(t1.created AS DATE) created,
COUNT(t1.field1) Enrolled,
COUNT(CASE t1.field1 WHEN 'E-mail' THEN 1 END) Enrolled_as_Email,
COUNT(CASE t1.field1 WHEN 'Cell Phone' THEN 1 END) Enrolled_as_Cell,
COUNT(t2.created) Deals_Redeemed
FROM tblCustomer AS t1
LEFT JOIN tbl_TransactionDishout t2
ON t1.cardno = t2.VirtualCard
GROUP BY CAST(t1.created AS DATE)
ORDER BY CAST(t1.created AS DATE) DESC
Edit: Changed condition to cardno, and changed from FULL JOIN to LEFT JOIN.
You could Pivot():
select [create]
, sum([Email]+[Cell Phone]) as [Enrolled]
, max([Email]) as [Enrolled as Email]
, max([Cell Phone]) as [Enrolled as Cell Phone]
, max([Deal Redeemed]) as [Deals Redeemed]
from (
select [create]=created
, create1=created
, field1
from tblCustomer
union all
select [create]=created
, create1=created
, field1='Deal Redeemed'
from tbl_TransactionDishout
) p
pivot (
count(create1)
for field1 in ([Cell Phone],[Email],[Deal Redeemed])
) pv
group by [create]
order by [create]

Resources