Retrieving data from unnormalized vertically ordered table - sql

I have the following relation:
employeevalue(id, name, value, code)
id name value code
101 bobby 150 100
101 bobby 12 150
101 bobby 14.6 200
102 mary 189 100
102 mary 128 150
102 mary 112 200
103 john 112 100
103 john 13 150
103 john 76 200
Where code 100 is value1, 150 is value2 and 200 is value3. How could I write an SQL statement to retrieve the following from this table?
id name value1 value2 value3
101 bobby 150 12 14.6
102 mary 189 128 112
103 john 112 13 76

You can do this with conditional aggregation:
select id,
max(case when code = 100 then value end) as value1,
max(case when code = 150 then value end) as value2,
max(case when code = 200 then value end) as value3
from table t
group by id;

Related

How to assign UniqueID on a table basted on multiple columns

I am wondering how to create a SQL Query to calculate if the row is unique based on certain columns(in this case InventoryID, CheckoutID, postal code, and UserID) to determine if its the first one that is unique then give it a value 1 if it has occurred again give it a 0.
Primary Key
StoreID
InventoryID
CheckoutID
Postal Code
UserID
1
101
201
301
111
A1
2
101
201
301
111
A1
3
102
202
302
112
A2
4
103
203
303
113
A3
5
104
204
304
114
A4
6
104
205
305
114
A4
7
104
205
305
114
A4
I am looking to add a column or out how to get it to look like this:
Primary Key
StoreID
InventoryID
CheckoutID
Postal Code
UserID
unique
1
101
201
301
111
A1
1
2
101
201
301
111
A1
0
3
102
202
302
112
A2
1
4
103
203
303
113
A3
1
5
104
204
304
114
A4
1
6
104
205
305
114
A4
1
7
104
205
305
114
A4
0
Assuming you are ordering by primary key, you can try this:
SELECT
"Primary Key", StoreID, InventoryID, CheckoutID, "Postal Code", UserID,
case WHEN row_num = 1 THEN 1 ELSE 0 END AS "unique"
FROM (
SELECT
*, ROW_NUMBER() OVER (PARTITION BY InventoryID, CheckoutID, "Postal Code", UserID ORDER BY "Primary Key") AS row_num
FROM my_table
) foo;

Exclude rows where keys match, but are on different rows

I'm looking for the best way to produce the result set in the scenario provided. My cust3 column isn't identifying the repeated values in the indvid2 column. The end result I'm looking for is to exclude the rows where key1 and key2 match (ids:1,2,6 and 7), then sum accounts where the acctids match.If there's a better way to code this, I welcome all suggestions. Thanks!
WITH T10 as (
SELECT acctid,invid,(
case
when invid like '%-R' then left (InvID,LEN(invid) -2) else InvID
END) as InvID2
FROM table x
GROUP BY acctID,invID
),
T11 as (
SELECT acctid, Invid2, COUNT(InvID2) as cust3
FROM T10
GROUP BY InvID2,acctid
HAVING
COUNT (InvID2) > 1
)
select DISTINCT
a.acctid,
a.name,
b.invid,
C.invid2,
D.cust3,
b.amt,
b.key1,
b.key2
from table a
inner join table b (nolock) on a.acctid = b.acctid
inner join T10 C (nolock) on b.invid = c.invid
inner join T11 D (nolock) on C.invid2 = D.invid2
Resultset
id acctID name invid invid2 Cust3 amt key1 key2
1 123 James 101 101 2 $500 NULL 6789
2 123 james 101-R 101 2 ($500) 6789 NULL
3 123 James 102 102 2 $350 NULL NULL
4 123 James 103 103 2 $200 NULL NULL
5 246 Tony 98-R 98 2 ($750) 7423 NULL
6 432 David 45 45 2 $100 NULL 9634
7 432 David 45-R 45 2 ($100) 9634 NULL
8 359 Stan 39-R 39 2 ($50) 6157 NULL
9 753 George 95 95 2 $365 NULL NULL
10 753 George 108 108 2 $100 NULL NULL
Desired Resultset
id acctID name invid invid2 Cust3 amt key1 key2
1 123 James 101 101 2 $500 NULL 6789
2 123 james 101-R 101 2 ($500) 6789 NULL
3 123 James 102 102 1 $350 NULL NULL
4 123 James 103 103 1 $200 NULL NULL
5 246 Tony 98-R 98 1 ($750) 7423 NULL
6 432 David 45 45 2 $100 NULL 9634
7 432 David 45-R 45 2 ($100) 9634 NULL
8 359 Stan 39-R 39 1 ($50) 6157 NULL
9 753 George 95 95 1 $365 NULL NULL
10 753 George 108 108 1 $100 NULL NULL
Then to sum amt by acctid
id acctid name amt
1 123 James $550
2 246 Tony ($750)
3 359 Stan ($50)
4 753 George $465
Something like:
;WITH Keys as (
SELECT Key1.acctID, [Key] = Key1.Key1
FROM YourTable as Key1
INNER JOIN YourTable as Key2
ON Key1.Key1 = Key2.Key2 and Key1.acctID = Key2.acctID
)
SELECT t.acctID, t.name, amt = SUM(t.amt)
FROM YourTable as t
LEFT JOIN Keys as k
ON t.acctID = k.acctID and (t.Key1 = [Key] or t.Key2 = [Key])
WHERE k.acctID is Null
GROUP BY t.acctID, t.name

Oracle select query based on multiple conditions

MESSAGE_ID GROUP_ID REV_NO
100 200 1
101 201 1
102 202 1
103 203 1
104 204 1
105 200 2
106 201 2
107 202 2
108 203 2
109 204 2
110 205 2
First I want to select all group ID's and their correpsponding lowest revision number.
Then I want select first X message ID's (Controllable X input) with condition that it should contain all the revisions of of any selected group. For e.g if I select first 5 messages by rownum then all revisions of group_id 200 is not selected.
Hope I made it clear.

oracle query - something similar to pivot, but

I have a table like this:
ID_ORIG ID_DEST DISTANCE
------- ------- --------
1 101 10
1 102 15
1 103 20
2 101 25
2 102 30
2 103 35
3 101 40
3 102 45
3 103 50
And I want the following result:
ID_ORIG 101 102 103
------- --- --- ---
1 10 15 20
2 25 30 35
3 40 45 50
I tried to use 'pivot', but obiously didn't achive this result. Database is Oracle 11g.
Any help would be appreciated.
Please try:
select * From(
select * from YourTable
) PIVOT (sum(DISTANCE) for (ID_DEST) IN (101, 102, 103));
SQL Fiddle Demo

update corresponding value from other table

I have two tables named sales and login.My table structure is given below.Some times my program update the custid instead of userid in sales table column userid, but the logid updated correctly in sales table. I have the another table tbl_log shown below. I want to update the sales table userid based on logid using the tbl_log.
sales table
Fld_id Fld_cust_id Fld_log_id Fld_amount Fld_user_id
1 S1002 101 100 d2121
2 S1003 102 121 S1003
3 S1004 103 120 d2123
4 S1005 102 130 d2122
5 S1006 102 1234 S1006
6 S1007 102 111 d2122
7 S1008 103 21 d2123
8 S1009 103 234 S1009
9 S1010 104 31 d2124
10 S1011 104 60 S1011
Log Table
Fld_log_id Fld_user_id
101 d2121
102 d2122
103 d2123
104 d2124
Exact output
Fld_id Fld_cust_id Fld_log_id Fld_amount Fld_user_id
1 S1002 101 100 d2121
2 S1003 102 121 d2122
3 S1004 103 120 d2123
4 S1005 102 130 d2122
5 S1006 102 1234 d2122
6 S1007 102 111 d2122
7 S1008 103 21 d2123
8 S1009 103 234 d2123
9 S1010 104 31 d2124
10 S1011 104 60 d2124
To update the values in sales based on the values in the log table you do:
UPDATE sales S
SET S.Fld_user_id = (SELECT l.Fld_user_id
FROM logSales l
WHERE l.Fld_log_id = s.Fld_log_id);
sqlfiddle demo