I have a data set which looks like
Group abc cde efg ...
PQR 70 60 50
LMN 30 40 30
XYZ 70 80 90
My data set contains around 35000 row & 30000 columns.
I need to write a SQL Query so that It can pool maximum value & the column contributing maximum. My Sample output looks like
Group Max Column
PQR 70 abc
LMN 40 cde
XYZ 90 efg
Can you suggest me how should I proceed ?
select Max(grp) grp,Max(abc) abc, Max(cde) cde,Max(efg) efg into #tmp2 from testtbl
select * from #tmp2
select grp,MX,qq from (select grp,abc,cde,efg from #tmp2) p
UNPIVOT (qq for MX in (
abc,cde,efg
)
) as unpvt
Related
In this the output need to get is that the value from the each id that should have only one value assign to that id(col1). if the same id has diff value no need to take that values and output.
Below is a sample table
Input Table 'Demo'
col1 col2
100 A
100 A
100 A
100 A
101 A
101 B
102 A
102 B
102 B
102 C
Output
col1 col2
100 A
100 A
100 A
100 A
You can use not exists :
select d.*
from Demo d
where not exists (select 1 from Demo d1 where d1.col1 = d.col1 and d1.col2 <> d.col2);
I have a table as below:
ID Product# Service# ServiceDate
1 100 122 2017-01-02
2 100 124 2017-03-02
3 122 133 2017-04-02
100 100 122 2017-05-02
I need to find the records that have the same product# and service# but different IDs. For this, I wrote the code below:
Select *
FROM MyTable as M1 Inner join
MyTable as M2 on
M1.Product#=M2.Product# and M1.Service#=M2.Service# and M1.ID!=M2.ID
However, I get duplicate results as such:
ID Product# Service# ServiceDate ID Product# Service# ServiceDate
1 100 122 2017-01-02 100 100 122 2017-05-02
100 100 122 2017-05-02 1 100 122 2017-01-02
Any idea how to eliminate these duplicate rows? I need to see a result as such:
ID Product# Service# ServiceDate ID Product# Service# ServiceDate
1 100 122 2017-01-02 100 100 122 2017-05-02
Try the following:
Select *
FROM MyTable as M1
Inner join MyTable as M2 on M1.Product#=M2.Product# and M1.Service#=M2.Service# and M1.ID!=M2.ID
where m1.id < m2.id
Explanation: Your example shows both sides of each coin; by limiting it to having one of the ID's being less than the other, you'll automatically have just half of the records, effectively getting you all unique combinations.
Bonus: For fun, I tried to add one more duplicate row to your sample data set, and it worked just as expected.
If you're wanting to return just two rows without the duplicate columns, replace
Select *
with
Select M1.*
I trying to create a table that will support a simple event study analysis, but I'm not sure how best to approach this.
I'd like to create a table with the following columns: Customer, Date, Time on website, Outcome. I'm testing the premise that the outcome for a particular customer on any give day if a function of the time spent on the website on the current day as well as the preceding five site visits. I'm envisioning a table similar to this:
I'm hoping to write a T-SQL query that will produce an output like this:
Given this objective, here are my questions:
Assuming this is indeed possible, how should I structure my table to accomplish this objective? Is there a need for a column that refers to the prior visit? Do I need to add an index to a particular column?
Would this be considered a recursive query?
Given the appropriate table structure, what would the query look like?
Is it possible to structure the query with a variable that determines the number of prior periods to include in addition to the current period (for example, if I want to compare 5 periods to 3 periods)?
Not sure I understand analytic value of your matrix
Declare #Table table (id int,VisitDate date,VisitTime int,Outcome varchar(25))
Insert Into #Table (id,VisitDate,VisitTime,Outcome) values
(123,'2015-12-01',100,'P'),
(123,'2016-01-01',101,'P'),
(123,'2016-02-01',102,'N'),
(123,'2016-03-01',100,'P'),
(123,'2016-04-01', 99,'N'),
(123,'2016-04-09', 98,'P'),
(123,'2016-05-09', 99,'P'),
(123,'2016-05-14',100,'N'),
(123,'2016-06-13', 99,'P'),
(123,'2016-06-15', 98,'P')
Select *
,T0 = VisitTime
,T1 = Lead(VisitTime,1,0) over(Partition By ID Order By ID,VisitDate Desc)
,T2 = Lead(VisitTime,2,0) over(Partition By ID Order By ID,VisitDate Desc)
,T3 = Lead(VisitTime,3,0) over(Partition By ID Order By ID,VisitDate Desc)
,T4 = Lead(VisitTime,4,0) over(Partition By ID Order By ID,VisitDate Desc)
,T5 = Lead(VisitTime,5,0) over(Partition By ID Order By ID,VisitDate Desc)
From #Table
Order By ID,VisitDate Desc
Returns
id VisitDate VisitTime Outcome T0 T1 T2 T3 T4 T5
123 2016-06-15 98 P 98 99 100 99 98 99
123 2016-06-13 99 P 99 100 99 98 99 100
123 2016-05-14 100 N 100 99 98 99 100 102
123 2016-05-09 99 P 99 98 99 100 102 101
123 2016-04-09 98 P 98 99 100 102 101 100
123 2016-04-01 99 N 99 100 102 101 100 0
123 2016-03-01 100 P 100 102 101 100 0 0
123 2016-02-01 102 N 102 101 100 0 0 0
123 2016-01-01 101 P 101 100 0 0 0 0
123 2015-12-01 100 P 100 0 0 0 0 0
With fixed columns you can do it like this with lag:
select
time,
lag(time, 1) over (partition by customer order by date desc),
lag(time, 2) over (partition by customer order by date desc),
lag(time, 3) over (partition by customer order by date desc),
lag(time, 4) over (partition by customer order by date desc)
from
yourtable
If you need dynamic columns, then you'll have to build it using dynamic SQL.
I have a table as below:
Name ValueA1 ValueA2 ValueA3 ValueB1 ValueB2 ValueB3 QtyA1 QtyA2 QtyA3 QtyB1 QtyB2 QtyB3
John 1 2 3 4 5 6 100 200 300 150 250 350
Dave 11 12 13 14 15 16 100 200 300 150 250 350
I am able to use unpivot to get the values:
select [Name]
, Replace(u.[Period],'Value','') as [Period]
, u.[Value]
from Table1
unpivot
(
[Value]
for [Period] in ([ValueA1], [ValueA2], [ValueA3], [ValueB1], [ValueB2], [ValueB3])
) u;
SQL Fiddle
However I'm trying to get both the Value and Qty columns on a single row, what I want to end up with is:
Name Number Value Qty
John A1 1 100
John A2 2 200
John A3 3 300
John B1 4 150
John B2 5 250
John B3 6 350
Dave A1 11 100
Dave A2 12 200
Dave A3 13 300
Dave B1 14 150
Dave B2 15 250
Dave B3 16 350
What I have so far is (which doesn't work at all):
select [Name]
, Replace(u.[Period],'Value','') as [Period]
, u.[Value]
, u2.[Value]
from Table1
unpivot
(
[Value]
for [Period] in ([ValueA1], [ValueA2], [ValueA3], [ValueB1], [ValueB2], [ValueB3])
) u
unpivot
(
[Qty]
for [Period] in ([QtyA1], [QtyA2], [QtyA3], [QtyB1], [QtyB2], [QtyB3])
) u2;
Is what I am trying to do even possible with unpivot?
You can use a simple apply for this by specifying the pairs in a values clause:
declare #table table (Name varchar(10), ValueA1 int, ValueA2 int, QtyA1 int, QtyA2 int);
insert into #table
select 'John', 1, 2, 100, 200 union all
select 'Dave', 11, 12, 100, 200;
select Name, Number, Value, Qty
from #table
cross
apply ( values
('A1', ValueA1, QtyA1),
('A2', ValueA2, QtyA2)
) c (number, value, qty);
If you're using an older edition of MSSQL, you might need to use this
instead of the values clause above:
cross
apply ( select 'A1', ValueA1, QtyA1 union all
select 'A2', ValueA2, QtyA2
) c (number, value, qty);
Returns:
Name Number Value Qty
John A1 1 100
John A2 2 200
Dave A1 11 100
Dave A2 12 200
I am trying to Create a SQL View by joining two SQL tables and return only the lowest value from second table and all the rows from first table similar to left join.
My problem can be clearly explained with the below example.
Table1
Id Product Grade Term Bid Offer
100 ABC A Q1 10 20
101 ABC A Q1 5 25
102 XYZ A Q2 25 30
103 XYZ B Q2 20 30
Table2
Id Product Grade Term TradeValue
1 ABC A Q1 100
2 ABC A Q1 95
3 XYZ B Q2 100
In the above data I want to join Table1 and Table2 when ever the columns Product,Grade and Term from both the tables are equal and return all the rows from Table1 while joining the lowest Value of the column TradeValue from Table2 to the first record of the match and making TradeValue as NULL for other rows of the resultant View and the resultant View should have the Id of Table2 as LTID
So the resultant SQL View should be
RESULT
Id Product Grade Term Bid Offer TradeValue LTID
100 ABC A Q1 10 20 95 2
101 ABC A Q1 5 25 NULL 2
102 XYZ A Q2 25 30 NULL NULL
103 XYZ B Q2 20 30 100 3
I tried using the following query
CREATE VIEW [dbo].[ViewCC]
AS
SELECT
a.Id,a.Product,a.Grade,a.Term,a.Bid,a.Offer,
b.TradeValue
FROM Table1 AS a
left JOIN (SELECT Product,Grade,Term,MIN(TradeValue) TradeValue from Table2 Group by Product,Grade,Term,) AS b
ON b.Product=a.Product
and b.Grade=a.Grade
and b.Term=a.Term
GO
The above Query returned the following data which is apt to the query I wrote but that is not what I was trying to get
Id Product Grade Term Bid Offer TradeValue
100 ABC A Q1 10 20 95
101 ABC A Q1 5 25 95 --This should be null
102 XYZ A Q2 25 30 NULL
103 XYZ B Q2 20 30 100
As we can see minimum value of TradeValue being assigned to all matching rows in Table1 and also I was not able to return Id As LTID from Table2 as I have issues with group by clause as I cannot group it by b.Id as it returns too many rows.
May I know a better way to deal with this?
You need a row number attached to each record from Table1, so that the requirement of only joining the first record from each group of Table1 can be fulfilled:
CREATE VIEW [dbo].[ViewCC]
AS
SELECT a.Id, a.Product, a.Grade, a.Term, a.Bid, a.Offer,
b.TradeValue, b.Id AS LTID
FROM (
SELECT *, ROW_NUMBER() OVER(PARTITION BY Product, Grade, Term ORDER BY Id) AS rn
FROM Table1
) a
OUTER APPLY (
SELECT TOP 1 CASE WHEN rn = 1 THEN TradeValue
ELSE NULL
END AS TradeValue, Id
FROM Table2
WHERE Product=a.Product AND Grade=a.Grade AND Term=a.Term
ORDER BY TradeValue) b
GO
OUTER APPLY returns a table expression containing either the matching record from Table2 with the lowest TradeValue, or NULL if no matching record exists.