Insert data from another table - sql

I've been stuck on this problem for a while
and here are there direction
Customers who have been invited to none of the “Mona Lisa” gala_night now get invited to to the 5-jan-2014 Mona Lisa gala_night. Show the insert command and the resulting Invite table.
Here are the two tables
SQL> select * from invite;
GALA_DATE PAINTING_NAME CUSTID
----------- ---------------------- ----------
10-nov-2013 Watercolors 1430
15-nov-2013 Woman 1502
15-nov-2013 Woman 1619
05-dec-2013 Watercolors 1207
22-dec-2013 Sunflowers 1806
22-dec-2013 Sunflowers 1904
31-dec-2013 Fiddler 1236
31-dec-2013 Fiddler 1280
05-jan-2014 Mona_Lisa 1111
05-jan-2014 Mona_Lisa 1502
25-jan-2014 Madonna 1806
25-jan-2014 Madonna 1822
25-jan-2014 Madonna 1904
18-feb-2014 Maya 1619
18-feb-2014 Maya 1822
18-feb-2014 Maya 1904
28-feb-2014 Mona_Lisa 1502
30-apr-2014 Lovers 1207
30-apr-2014 Lovers 1280
30-apr-2014 Lovers 1822
30-apr-2014 Lovers 1904
SQL> select * from customer;
CUSTID CUSTNAME CUSTBDATE CUST_TYPE BENEFACTOR DOCENT
1301 Disney 01-nov-1980 NM No No
1806 Garcia 31-dec-2000 VIP Yes No
1502 LaGardia 15-jan-1960 VIP Yes Yes
1207 Perry 20-jan-1960 VIP Yes Yes
1280 Beecham 31-dec-1979 VIP Yes No
1822 Becker 30-jan-1967 VIP Yes Yes
1140 Klim 05-apr-1990 NM No No
1509 Roberts 21-jul-1989 VIP Yes No
1619 Robins 20-feb-1990 VIP Yes Yes
1111 Bardot 28-feb-1970 VIP No No
1515 David 18-apr-1980 NM No No
1701 Martin 20-aug-1972 RM No No
1904 Gross 30-sep-1975 VIP Yes Yes
1236 Brooks 23-sep-1975 VIP Yes No
1430 Todd 15-jul-1982 VIP Yes Yes
I've tried doing
insert into invite(gala_date,painting_name,custid)
select invite.gala_date,invite.painting_name,invite.custid
from invite,customer
where invite.gala_date='05 Jan 2014' and invite.painting_name='Mona_Lisa'
and customer.custid=invite.custid
and customer.custid not in
(select custid from invite where gala_date in('05 Jan 2014')
and painting_name in('Mona_Lisa'));
0 rows created.
But as you can see the results yield "0 rows created"
Any thoughts?
Thanks!

You just need to use a not exists to get the results you want.
insert into invite(gala_date,painting_name,custid)
select '01/05/2014', 'Mona_Lisa', customer.custid
From customer
Where Not Exists (select '' from invite where invite.custid = customer.custid and painting_name = 'Mona_Lisa')

try this
insert into invite(gala_date,painting_name,custid)
select '01/05/2014', 'Mona_Lisa', a.custid
from customer a
left join invite b on (a.custid = b.custid and b.PaintingName = 'Mona_Lisa'
where b.custid is null
I think that will get you close, might need to tweak it as I didn't check

Related

SQL join to identify group members

I have got a client table which pretty much looks like below:
Client List
customer no. Customer name
123 Kristen Smith
128 Jeremy Church
127 Alan Li
132 Ryan Nelson
I need to map it to a Customer_Dim table
Customer_Dim
customer no. Customer name Group no. Group Name Cust_Active Flag
123 Kristen Smith 5491 Zealong Tea Estate Y
167 Anna Hathaway 5823 AA Insurance Y
146 Simon Joe 5671 Direct Automobile Y
148 Henry Wilson 5823 AA Insurance Y
195 Graham Brown 5491 Zealong Tea Estate Y
172 Daria Smith 5671 Direct Automobile N
122 Dyana Smith 5823 AA Insurance N
132 Ryan Nelson 5671 Direct Automobile N
128 Jeremy Church 5823 AA Insurance Y
127 Alan Li 5671 Direct Automobile Y
to get their group numbers from below table (which I am able to do by a simple left join)
to list all the remaining customers (who are active) from the group numbers of the client customer [I AM UNABLE TO DO THIS 2nd PART] :
Required Results :
Customer No. Customer name Group No. Group Name
123 Kristen Smith 5491 Zealong Tea Estate
128 Jeremy Church 5823 AA Insurance
127 Alan Li 5671 Direct Automobile
195 Graham Brown 5491 Zealong Tea Estate
167 Anna Hathaway 5823 AA Insurance
148 Henry Wilson 5823 AA Insurance
146 Simon Joe 5671 Direct Automobile
Please let me know if any other information is needed.
Sorry, if a similar question has been asked earlier - did several searches but was unable to find anything.
Thanks
join the tables to get all the group numbers of the clients in the client list and then select from customer_dim only the clients of these group numbers who are active:
select * from customer_dim
where
cust_active_flag = 'Y'
and
groupno in (
select groupno
from client_list l inner join customer_dim d
on d.customerno = l.customerno
)
See the demo.
Results:
> customerno | customername | groupno | groupname | cust_active_flag
> ---------: | :------------ | ------: | :----------------- | :---------------
> 123 | Kristen Smith | 5491 | Zealong Tea Estate | Y
> 167 | Anna Hathaway | 5823 | AA Insurance | Y
> 146 | Simon Joe | 5671 | Direct Automobile | Y
> 148 | Henry Wilson | 5823 | AA Insurance | Y
> 195 | Graham Brown | 5491 | Zealong Tea Estate | Y
> 128 | Jeremy Church | 5823 | AA Insurance | Y
> 127 | Alan Li | 5671 | Direct Automobile | Y
for get required results you need a condition in your join
SELECT *
FROM Client c
JOIN Customer_Dim cd on c.CustomerNo = cd.CustomerNo
and cd.Cust_ActiveFlag ='Y'
or
SELECT *
FROM Client c
JOIN Customer_Dim cd on c.CustomerNo = cd.CustomerNo
WHERE cd.Cust_ActiveFlag ='Y'
I think it is pretty simple to get your posted result from Customer_Dim table.
if you don't want Group No. of ClientList
select * from Customer_Dim
where [Cust_Active Flag] = 'Y'
and [Group No.] not in (
select CD.[Group No.] from [Client List] as CL inner join Customer_Dim as CD where CL.[customer no.] = CD.[customer no.] )
And
if you only want Group No. of ClientList
select * from Customer_Dim
where [Cust_Active Flag] = 'Y'
and [Group No.] in (
select CD.[Group No.] from [Client List] as CL inner join Customer_Dim as CD where CL.[customer no.] = CD.[customer no.] )
For the case of a client being inactive and wanting to identify the client in the result set you can do a LEFT JOIN with a GROUP BY and leverage Proc SQL automatic remerging in a HAVING clause for selection criteria.
data client_list; input
custno custname:& $30.; datalines;
123 Kristen Smith
128 Jeremy Church
127 Alan Li
132 Ryan Nelson
899 Julius Caesar
run;
data customer_dim; input
custno custname:& $30. groupnum groupname:& $30. Cust_Active_Flag: $1.; datalines;
123 Kristen Smith 5491 Zealong Tea Estate Y
167 Anna Hathaway 5823 AA Insurance Y
146 Simon Joe 5671 Direct Automobile Y
148 Henry Wilson 5823 AA Insurance Y
195 Graham Brown 5491 Zealong Tea Estate Y
172 Daria Smith 5671 Direct Automobile N
122 Dyana Smith 5823 AA Insurance N
132 Ryan Nelson 5671 Direct Automobile N
128 Jeremy Church 5823 AA Insurance Y
127 Alan Li 5671 Direct Automobile Y
231 Donald Duck 7434 Orange Insurance Y
899 Julius Caesar 4999 Emperors N
900 Joshua Norton 4999 Emperors N
925 Joaquin Guzman 4999 Emperors Y
925 Naruhito 4999 Emperors Y
run;
proc sql;
create table want(label="Active customers of clients groups") as
select
LIST.custno as client,
DIM.*
from
customer_dim DIM
left join
client_list LIST
on
DIM.custno = LIST.custno
group by
groupnum
having
N(LIST.custno) > 0
and
(
cust_active_flag = 'Y'
or LIST.custno is not NULL
)
order by
groupnum, custno
;

Stored Procedure Select from 3 tables

I have three tables in my database Sales, SalesPeople and Appliances.
Sales
SaleDate EmployeeID AppID Qty
---------- ---------- ----- -----------
2010-01-01 1412 150 1
2010-01-05 3231 110 1
2010-01-03 2920 110 2
2010-01-13 1412 100 1
2010-01-25 1235 150 2
2010-01-22 1235 100 2
2010-01-12 2920 150 3
2010-01-14 3231 100 1
2010-01-15 1235 300 1
2010-01-03 2920 200 2
2010-01-31 2920 310 1
2010-01-05 1412 420 1
2010-01-15 3231 400 2
SalesPeople
EmployeeID EmployeeName CommRate BaseSalary SupervisorID
---------- ------------------------------ ----------- ----------- ------------
1235 Linda Smith 15 1200 1412
1412 Anne Green 12 1800 NULL
2920 Charles Brown 10 1150 1412
3231 Harry Purple 18 1700 1412
Appliances
ID AppType StoreID Cost Price
---- -------------------- ------- ------------- -------------
100 Refrigerator 22 150 250
110 Refrigerator 20 175 300
150 Television 27 225 340
200 Microwave Oven 22 120 180
300 Washer 27 200 325
310 Washer 22 280 400
400 Dryer 20 150 220
420 Dryer 22 240 360
How can I obtain this result? (That displays the profitability of each of the salespeople ordered from the most profitable to the least. Gross is simply the sum of the quantity of items sold multiplied by the price. Commission is calculated from the gross minus the cost of those items (i.e. from
qty*(price-cost)). Net profit is the total profit minus commission.)
Name Gross Commission Net Profit
------------- ----- ---------- ---------
Charles Brown 2380 83.5 751.5
Linda Smith 1505 83.25 471.75
Harry Purple 990 65.7 299.3
Anne Green 950 40.2 294.8
My attempt:
CREATE PROC Profitability AS
SELECT
sp.EmployeeName, (sum(s.Qty) * a.Price) as [Gross],
[Gross] - a.Cost, as [Commision],
SOMETHING as [Net Profit]
FROM
Salespeople sp, Appliances a, Sales s
WHERE
s.AppID = a.ID
AND sp.EmployeeID = s.EmployeeID
GROUP BY
sp.EmployeeName
GO
EXEC Profitability
Simple rule: Never use commas in the FROM clause. Always use explicit JOIN syntax.
In addition to fixing the JOIN syntax, your query needs a few other enhancements for the aggregation functions:
SELECT sp.EmployeeName, sum(s.Qty * a.Price) as Gross,
SUM(s.Qty * (a.Price - a.Cost)) * sp.CommRate / 100.0 as Commission,
SUM(s.Qty * (a.Price - a.Cost)) * (1 - sp.CommRate / 100.0) as NetProfit
FROM Sales s JOIN
Salespeople sp
ON sp.EmployeeID = s.EmployeeID JOIN
Appliances a
ON s.AppID = a.ID
GROUP BY sp.EmployeeName sp.CommRate
ORDER BY NetProfit DESC;

How to number records based on values

I have the following data
FieldA FieldB FieldC FieldD
1234 01/05/14 Mark John
3234 05/04/2014 Mark Smith
3232 05/09/2013 Kara Sidney
3554 06/08/2012 Lamar Angela
5668 01/01/2011 Kara Rick
I have 15 Million Similar records in a data set.
I would like to create a query that would give unique numbers to "Mark, Kara, Lamar" whenever they appear to be their unique number.
FieldA FieldB FieldC FieldD FieldE
1234 01/05/14 Mark John 1
3234 05/04/2014 Mark Smith 1
3232 05/09/2013 Kara Sidney 2
3554 06/08/2012 Lamar Angela 3
5668 01/01/2011 Kara Rick 2
how can I do that?
If you really want to get crazy, here's a solution:
SELECT [FieldA], [FieldB], a.[FieldC], [FieldD], [FieldE]
FROM [TABLE] a
LEFT JOIN(
SELECT DISTINCT [FieldC], pwdencrypt([FieldC]) as [FieldE]
FROM [TABLE]) b
ON a.[FieldC] = b.[FieldC]
That pwdencrypt() creates a very unique id.

Incremental count in SQL Server 2005

I am working with a Raiser's Edge database using SQL Server 2005. I have written SQL that will produce a temporary table containing details of direct debit instalments. Below is a small table containing the key variables for the question I'm going to ask, with some fictional data:
Donor_ID Instalment_ID Instalment_Date Amount
1234 1111 01/01/2011 £5.00
1234 1112 01/02/2011 £0.00
1234 1113 01/03/2011 £5.00
1234 1114 01/04/2011 £5.00
1234 1115 01/05/2011 £0.00
1234 1116 01/06/2011 £0.00
2345 2111 01/01/2011 £0.00
2345 2112 01/02/2011 £5.00
2345 2113 01/03/2011 £5.00
2345 2114 01/04/2011 £0.00
2345 2115 01/05/2011 £0.00
2345 2116 01/06/2011 £0.00
As you will see, some of the values in the Amount column are £0.00. This can occur when a donor has insufficient funds in their account, for example.
What I'd like to do is write a SQL query that will create a field containing an incremental count of consecutive £0.00 payments that resets after a non-£0.00 payment or after a change in Donor_ID. I have reproduced the above data below, with the field I'd like to see.
Donor_ID Instalment_ID Instalment_Date Amount New_Field
1234 1111 01/01/2011 £5.00
1234 1112 01/02/2011 £0.00 1
1234 1113 01/03/2011 £5.00
1234 1114 01/04/2011 £5.00
1234 1115 01/05/2011 £0.00 1
1234 1116 01/06/2011 £0.00 2
2345 2111 01/01/2011 £0.00 1
2345 2112 01/02/2011 £5.00
2345 2113 01/03/2011 £5.00
2345 2114 01/04/2011 £0.00 1
2345 2115 01/05/2011 £0.00 2
2345 2116 01/06/2011 £0.00 3
To help clarify what I'm looking for, I think what I'm looking to do would be similar to a winning streak field on a list of a football team's results. For example:
Opponent Score Winning_Streak
Arsenal 1-0 1
Liverpool 0-0
Swansea 3-1 1
Chelsea 2-1 2
Fulham 4-0 3
Stoke 0-0
Man Utd 1-3
Reading 2-1 1
I've considered various options, but have made no progress. Unless I've missed something obvious, I think that a solution more advanced than my current SQL programming level might be required.
If I am thinking about this problem correctly, I believe that you want a row number when the Amount is 0.00 pounds.
Select 0 as As InsufficientCount
, Donor_ID
, Installment_ID
, Amount
From [Table]
Where Amount > 0.00
Union
Select Row_Number() Over (Partition By Donor_ID Order By Installment_ID)
, Donor_ID
, Installment_ID
, Amount
From [Table]
Where Amount = 0.00
This union select should only give you 'ranks' where the Amount equals 0.
Am calling your new field streakAmount
ALTER TABLE instalments ADD streakAmount int NULL;
Then, to update the value:
UPDATE instalments
SET streakAmount =
(SELECT
COUNT(*)
FROM
instalments streak
WHERE
streak.donor_id = instalments.donor_id
AND
streak.instalment_date <= instalments.instalment_date
AND
(streak.instalment_date >
-- find previous instalment date, if any exists
COALESCE(
(
SELECT
MAX(instalment_date)
FROM
instalments prev
WHERE
prev.donor_id = instalments.donor_id
AND
prev.amount > 0
AND
prev.instalment_date < instalments.instalment_date
)
-- otherwise min date
, cast('1753-1-1' AS date))
)
)
WHERE
amount = 0;
http://sqlfiddle.com/#!6/a571f/18

Can't GROUP BY correctly (SQL)

I have an SQL query that currently displays all the people in table HOTEL that booked a hotel between $260 and $350. I'm using ORACLE
SELECT guest.guest_name "GUEST NAME",
Count(guest.guest_no),
guest.guest_no "GUEST NUMBER",
room.r_price "ROOM PRICE"
FROM room,
guest,
booking
WHERE r_price >= 260
AND r_price <= 350
AND guest.guest_no = booking.guest_no
GROUP BY guest.guest_no,
guest.guest_name,
room.room_price
ORDER BY guest.guest_name;
I thought that I could group by just GUEST.GUEST_NAME (so it puts all of the count under the one name rather than doubling up on the guest names).
EDIT: The current results of the query look like this:
GUEST NAME COUNT GUEST_NO R_PRICE
Jenny Freeman 2 G003 260
Jenny Freeman 2 G003 295
Jenny Freeman 2 G003 310
Martin Ferguson 3 G006 260
Martin Ferguson 3 G006 295
Martin Ferguson 3 G006 310
Paul Happy 3 G002 260
Paul Happy 3 G002 295
Paul Happy 3 G002 310
Steve Kirkwood 3 G005 260
Steve Kirkwood 3 G005 295
Steve Kirkwood 3 G005 310
Tina Duncan 2 G001 260
Tina Duncan 2 G001 295
Tina Duncan 2 G001 310
Vanessa Horton 1 G007 260
Vanessa Horton 1 G007 295
Vanessa Horton 1 G007 310
But I'm expecting something like this:
GUEST NAME COUNT GUEST_NO R_PRICE
Jenny Freeman 6 G003 260
Martin Ferguson 9 G006 310
Paul Happy 9 G002 310
Steve Kirkwood 9 G005 260
Tina Duncan 6 G001 310
Vanessa Horton 3 G007 260
Well, I think you just have to change in group by statement rest looks OK to me. Just don't include Room price in Group By statement, i think that is creating problem for you if i am getting your question right...
GROUP BY GUEST.GUEST_NO,
GUEST.GUEST_NAME
and
MAX(R_PRICE)
May be you forgot to join ROOM with BOOKING by ROOM_NO (or other field)?
I've removed ROOM PRICE from group by, query now will will return unique guests and number of rooms they booked with price in given range, and max price for each guest.
SELECT
GUEST.GUEST_NAME "GUEST NAME",
GUEST.GUEST_NO "GUEST NUMBER",
COUNT(*) "CNT",
MAX(R.R_PRICE) "ROOM PRICE"
FROM BOOKING B
inner join ROOM R on R.ROOM_NO = B.ROOM_NO
inner join GUEST G on G.GUEST_NO = B.GUEST_NO
WHERE R.R_PRICE>=260 and R.R_PRICE<=350
GROUP BY G.GUEST_NO, G.GUEST_NAME
ORDER BY G.GUEST_NAME;
You can try the below sql query:
SELECT GUEST.GUEST_NAME "GUEST NAME", COUNT(GUEST.GUEST_NO), GUEST.GUEST_NO "GUEST NUMBER", ROOM.R_PRICE "ROOM PRICE"
FROM ROOM, GUEST,BOOKING
WHERE ROOM.R_PRICE>=260
AND ROOM.R_PRICE<=350
AND GUEST.GUEST_NO = BOOKING.GUEST_NO
GROUP BY GUEST.GUEST_NAME
ORDER BY GUEST.GUEST_NAME;