sql query to link two tables - sql

I have a table called users where the employee data are stored.
Also I have another table payment_details where employee's payment related data are stored
the two tables are as follows.
this table is users
sr_no emp_no username payment
1 1001 leroy <null>
2 1003 harry <null>
3 1004 Tom <null>
4 1008 Jon <null>
This table below is payment_details
sr_no name number month status date
43 Jon 1008 January paid 5/16/2012
44 Jon 1008 January balance 5/16/2012
45 Harry 1003 January paid 5/16/2012
46 Tom 1004 January paid 5/16/2012
47 leroy 1001 January paid 5/16/2012
48 Jon 1008 January paid 5/16/2012
49 Harry 1003 January paid 5/16/2012
50 Jon 1008 February balance 5/16/2012
51 leroy 1001 February paid 5/16/2012
52 Jon 1008 February paid 5/16/2012
53 Tom 1004 February balance 5/16/2012
My question here is to update "users" table payment column to "paid" when the status of his/her is all paid in payment_details table

You can either do this: http://www.sqlfiddle.com/#!3/db13f/18
update users set payment = 'paid'
from
(
select number
from payment_details
group by number
having sum(case when status = 'paid' then 1 end)
= count(*)
) as x
where x.number = users.emp_no;
Or this: http://www.sqlfiddle.com/#!3/db13f/19
update users
set payment = x.upd
from
(
select u.emp_no,
case when sum(case when d.status = 'paid' then 1 end) = count(*) then
'paid'
else
null
end as upd
from users u
left join payment_details d
on d.number = u.emp_no
group by u.emp_no
) as x
where x.emp_no = users.emp_no;
Their difference is how many rows it updates. On the second query, it updates all users, regardless if the user has a paid all status('paid') or not(null); on the first query, it updates only those who are paid.
The advantage of the second query, is when you change one of the all 'paid' status on payment_detail of a given user to 'not paid' for example, it can revert back the user's payment status to null

UPDATE order_details
SET payment= 'paid'
WHERE not EXISTS (SELECT 1
FROM payment_details
WHERE payment_details.emp_no= order_details.emp_no
AND payment_details.status <> 'paid'
)

There also simple way to get the value of particulars table into variable and update the tabe as below:
declare #bb varchar(50)
select #bb= status from payment_details where name=#name and id=#id
update uuser set payment = #bb
where name = #name and id=#id

Related

MS Access SQL, How to return only the newest row before a given date joined to a master table

I have two tables in a MS Access database as shown below. CustomerId is a primary key and fkCustomerId is a foreign key linked to the CustomerId in the other table.
Customer table
CustomerId
Name
1
John
2
Bob
3
David
Purchase table
fkCustomerId
OrderDate
fkStockId
1
01/02/2010
100
3
08/07/2010
101
2
14/01/2011
102
2
21/10/2011
103
3
02/03/2012
104
1
30/09/2012
105
3
01/01/2013
106
1
18/04/2014
107
3
22/11/2015
108
I am trying to return a list of customers showing the last fkStockId for each customer ordered before a given date.
So for the date 01/10/2012, I'd be looking for a return of
fkCustomerId
Name
fkStockId
1
John
105
2
Bob
103
3
David
104
A solution seems to be escaping me, any help would be greatly appreciated.
You can use nested select to get last order date.
SELECT Purchase.fkCustomerId,
Name,
fkStockId
FROM Purchase
JOIN
(
SELECT fkCustomerId,
MAX(OrderDate) as last_OrderDate
FROM Purchase
WHERE OrderDate < '01/10/2012'
GROUP BY fkCustomerId
) AS lastOrder
ON lastOrder.fkCustomerId = Purchase.fkCustomerId
AND last_OrderDate = OrderDate
LEFT JOIN Customer
ON Customer.CustomerId = Purchase.fkCustomerId
This example assumes OrderDate before '01/10/2012'. You might need to change it if you want it to be filtered by a different value.
Another assumption is that there's only one corresponding fkStockId for each OrderDate

Select all transactions that contain a specific item?

Good Morning,
The question I am running into involves a database with transactions. The transactions are stored as lines by each item sold. What would the code be if I wanted to select all transactions which contained item 11222 so I can see what other items are bought with it?
I was using:
SELECT [Transaction]
, [Date]
, [Item]
, [Register]
, [Location]
WHERE [Item] = 11222
FROM "Transactions"
Then looking up each transaction with date and location separately to see, however my request is now to look at thousands of transactions. Is there a way in SQL to conditionally pull all lines, even if the specific line doesn't contain the requested item #?
Example of how the data is in the table:
Transaction Date Item Register Location
123 1/1/2019 11222 1 15
123 1/1/2019 45663 1 15
124 1/1/2019 77433 1 15
124 1/1/2019 11222 1 15
124 1/1/2019 66092 1 15
125 1/1/2019 66933 1 15
125 1/1/2019 77433 1 15
126 1/1/2019 11222 1 15
126 1/1/2019 82991 1 15
127 1/1/2019 88392 1 15
127 1/1/2019 88492 1 15
I would phrase this as exists:
SELECT t.*
FROM Transactions t
WHERE EXISTS (SELECT 1
FROM Transactions t2
WHERE t2.transaction = t.transaction AND
t2.Item = 11222
)
ORDER BY t.transaction; -- keep all the rows for a given transaction together

Getting a count while accounting for an attribute

I have two tables, one for account information and one for customer information. An account can have multiple customers associated with it. What I want to do is grab all active customers in a given month. However, I also want to account for customers who are active and purchased in earlier months.
Account
ID IND_ID LAST_PURCHASE
1 101 2013-01-15
2 102 2013-03-20
2 103 2013-02-05
3 104 2013-07-25
4 105 2012-01-11
Customer
ID STATUS
101 A
102 A
103 A
104 E
105 A
Select just the active customers is not the issue as I can just filter on that column. However, how can I select the count of active 'customers' while accounting for people who purchased in the past two month.
You can do this by looking at the maximum purchase date and filtering on that:
select c.id
from customer c join
account a
on c.id = a.ind_id
where c.status = 'A'
group by c.id
having max(last_purchase) >= date_add(month, -2, getdate());

SQL: How do I count the number of clients that have already bought the same product?

I have a table like the one below. It is a record of daily featured products and the customers that purchased them (similar to a daily deal site). A given client can only purchase a product one time per feature, but they may purchase the same product if it is featured multiple times.
FeatureID | ClientID | FeatureDate | ProductID
1 1002 2011-05-01 500
1 2333 2011-05-01 500
1 4458 2011-05-01 500
2 8888 2011-05-10 700
2 2333 2011-05-10 700
2 1111 2011-05-10 700
3 1002 2011-05-20 500
3 4444 2011-05-20 500
4 4444 2011-05-30 500
4 2333 2011-05-30 500
4 1002 2011-05-30 500
I want to count by FeatureID the number of clients that purchased FeatureID X AND who purchased the same productID during a previous feature.
For the table above the expected result would be:
FeatureID | CountofReturningClients
1 0
2 0
3 1
4 3
Ideally I would like to do this with SQL, but am also open to doing some manipulation in Excel/PowerPivot. Thanks!!
If you join your table to itself, you can find the data you're looking for. Be careful, because this query can take a long time if the table has a lot of data and is not indexed well.
SELECT t_current.FEATUREID, COUNT(DISTINCT t_prior.CLIENTID)
FROM table_name t_current
LEFT JOIN table_name t_prior
ON t_current.FEATUREDATE > t_prior.FEATUREDATE
AND t_current.CLIENTID = t_prior.CLIENTID
AND t_current.PRODUCTID = t_prior.PRODUCTID
GROUP BY t_current.FEATUREID
"Per feature, count the clients who match for any earlier Features with the same product"
SELECT
Curr.FeatureID
COUNT(DISTINCT Prev.ClientID) AS CountofReturningClients --edit thanks to feedback
FROM
MyTable Curr
LEFT JOIN
MyTable Prev WHERE Curr.FeatureID > Prev.FeatureID
AND Curr.ClientID = Prev.ClientID
AND Curr.ProductID = Prev.ProductID
GROUP BY
Curr.FeatureID
Assumptions: You have a table called Features that is:
FeatureID, FeatureDate, ProductID
If not then you could always create one on the fly with a temporary table, cte or view.
Then:
SELECT
FeatureID
, (
SELECT COUNT(DISTINCT ClientID) FROM Purchases WHERE Purchases.FeatureDate < Feature.FeatureDate AND Feature.ProductID = Purchases.ProductID
) as CountOfReturningClients
FROM Features
ORDER BY FeatureID
New to this, but wouldn't the following work?
SELECT FeatureID, (CASE WHEN COUNT(clientid) > 1 THEN COUNT(clientid) ELSE 0 END)
FROM table
GROUP BY featureID

T-SQl Query Problem

I have a table called CorporateTree and Production and the tables have data like:
Table: CorporateTree
DivisionName RegionName CommonName BU
Central Region 1 Raintree 101
Central Region 1 Glenwood 102
East Region 2 Balsa 201
East Region2 Warren 202
Table: Production
ProdID BU ResidentName ResidentID Room
1 101 Smith, Jeff 234859 1002-A
2 202 Mill, Steve 125467 2002-B
3 101 Sisk, Paul 4383943 1009-C
4 101 Sims, Gary 384393 1010-A
5 202 Mason, Sam 32902 1012-A
I am looking to get output like this:
Division Region Facility Business Unit ResidentCount Status
Central Region 1 Glenwood 102 0 Flag
Central Region 1 Raintree 101 3
East Region 2 Balsa 201 0 Flag
East Region 2 Warren 202 2
if the Number of Residents is zero (0) output the value of “Flag” in a Status
i tried this query:
SELECT ct.DivisionName,ct.RegionName,ct.CommonName AS Facility,ct.BU AS [Business Unit],
(SELECT ROW_NUMBER() OVER (PARTITION BY p.BU ORDER BY p.BU DESC)) AS ResidentCount FROM
CorporateTree ct INNER JOIN Production p ON
p.Bu = ct.BU
But it doesn't seem to be working? Can any one help me on this?
You'll want to use a LEFT JOIN to account for any Business Units that have no rows in the Production table.
SELECT ct.DivisionName, ct.RegionName, ct.CommonName AS Facility, ct.BU AS [Business Unit],
COUNT(p.BU) as ResidentCount,
CASE WHEN COUNT(p.BU) = 0 THEN 'Flag' ELSE '' END AS Status
FROM CorporateTree ct
LEFT JOIN Production p
ON p.BU = ct.BU
GROUP BY ct.DivisionName, ct.RegionName, ct.CommonName, ct.BU