I know I can do a count from mysql by doing this:
Select customer, Count (customer) Numbers from TblOrders group by customer
I want to count how many times each customer appears in the Order table.
After that I want to update Order table by swapping the customer id of the customer with the highest number of orders with another customer with id = 1.
Customer | Numbers
1 | 5
2 | 18
3 | 0
so here the highest was C2 so it'll swap C1 with C2 now after performing another count, I should get the table below.
Customer | Numbers
1 | 18
2 | 5
3 | 0
I also know the swapping can be done this way from a little research I've done.
Update TblOrders Set Customer = Case when 1 then 2
when 2 then 1
end
where TblOrders in (1, 2)
the problem with this statement is that it assumes I already know the two ID's that I'm swapping. but in case I don't know but I want the second one to be the ID with the highest number of orders...how do I go about it?
You want to issue an UPDATE request which affects all rows that belong to either one of the two customers in question. So the basic idea is this:
UPDATE TblOrders
SET customer = IF(customer == 'C1', #MaxCust, 'C1')
WHERE customer IN ('C1', #MaxCust)
If your customer IDs were integers, you could abbreviate this to
UPDATE TblOrders
SET customer = 1 + #MaxCust - customer
WHERE customer IN (1, #MaxCust)
This works because a + b - a = b and a + b - b = a, so a and b are exchanged.
My notation above was using a user variable #MaxCust to store the ID of the customer to be swapped. Depending on your environment, you might also use application code to enter the correct value into the query. Using a user variable, you could set it like this:
SELECT customer
FROM TblOrders GROUP BY customer
ORDER BY COUNT(*) DESC
LIMIT 1
INTO #MaxCust
after taking a look at # MvG's solutions, I came up with my own solution which is below.
SELECT customer FROM TblOrders GROUP BY customer ORDER BY COUNT(*) DESC LIMIT 1 INTO #MaxCust;
Update TblOrders Set Customer = Case
when 1 then #MaxCust
when #MaxCust then 1
end
where TblOrders in (1, #MaxCust );
Related
I am trying to count matching values from customer column on table 'Customers' and update their values on the Count Column in table 'Summary'. I also want to Check if the Date is <= Todays Date.
Table "Customers":
ID
Customer
Date
1
John
2022-01-01
2
John
2022-01-01
3
Mary
2022-01-01
4
Mary
2022-01-01
.......+2000 More Customers
Table "Summary":
ID
Customer
Count
DateInput
1
John
2
2021-01-01
2
Mary
2
2021-01-01
.........+100 More Customers
I can update one row at a time like this:
update Summary
set Count = (SELECT COUNT(*)
FROM Customers
WHERE Customer = "John" AND Date <=CURRENT_DATE())
WHERE Customer = "John";
Is there a way to use the above query to update the count column for John, mary, etc, etc without doing Multiple individual requests?
Is this something you are looking for?
UPDATE
Summary s
INNER JOIN Customers c ON s.Customer = c.Customer
SET
s.Count = (
SELECT
COUNT(*)
FROM
Customers c2
WHERE
c2.Customer = s.Customer
AND c2.Date <= CURRENT_DATE()
)
If you are going to test the query, please test it on a small dataset before applying it to the entire table since it may not achieve the results you are expecting.
Given that your count values will change, you should consider creating a view instead of updating a table:
CREATE VIEW summary AS
SELECT ID, Customer, COALESCE(COUNT(CASE WHEN Date <= CURRENT_DATE() THEN 1 END), 0) AS cnt
FROM Customers
GROUP BY ID, Customer
If you really want to have a table and update it every time, you need such UPDATE statement:
WITH cte AS (
SELECT ID, Customer, COUNT(*) AS count
FROM Customers
WHERE Date <= CURRENT_DATE()
GROUP BY ID, Customer
)
UPDATE Summary
INNER JOIN cte ON Summary.ID = cte.ID AND Summary.Customer = cte.Customer
SET Summary.count = cte.count
You can do it as follows :
UPDATE Summary s
INNER JOIN (
SELECT Customer, count(1) as _count
FROM Customers
where Date <=CURRENT_DATE()
group by Customer
) as c on s.Customer = c.Customer
set s.Count = c._count ;
I have used inner join to join a list of customers and their counts.
and the relation is Customer.
I have a table for payments. It has a column named user_id, & payment_type. For every payment, a user can have multiple payment types.
I want to find the users that have used only one payment_type in their entire lifetime.
Let me make it clear through an example:
Let's say I have the following data:
user_id payment_type
1 UPI
1 NB
2 UPI
2 UPI
For the above, I only want user_id 2 as the output since for both the payments, it has used only 1 payment_type.
Can someone help?
A simple HAVING with COUNT should do the trick:
select user_id
from my_table
group by user_id
having count(distinct payment_type)=1;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=65f673a7df3ac0ee18c13105a2ec17ad
If you want to include payment_type in the result set , use:
select my.user_id,my.payment_type
from my_table my
inner join ( select user_id
from my_table
group by user_id
having count(distinct payment_type)=1
) as t1 on t1.user_id=my.user_id
group by my.user_id,my.payment_type ;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=cc4704c9e51d01e4e8fc087702edbe6e
I need to create a query from 2 tables, where my company stores e-shop information.
Example of data from the first table:
currentDate: 5.5.2022 | eshopId: 1 | eshopName: test | active: true |
Table 2:
currentDate: 5.5.2022 | eshopId: 1 | orderId: 123 | attribution: direct |
From the first table, I want get how many days in a given period the eshop was active. From the second table, I would like to count all the orders that were attributed directly to our company in the same time period as in the first table.
SELECT i.id, count(*)
from table1 as i
FULL JOIN table1 as e ON e.id= i.id
WHERE i.active = TRUE
GROUP BY i.id
I tried merging the same table twice, because after I used count to get amount of inactive dates, I could not use another variable as it was not aggregated. This still does not work. I cannot imagine how I would do this for 3 tables. Can someone please point me in the right direction on how to do this? Thanks.
If there is one row for each day per eshopId and you want to count number of active days along with number of order per eshopId:
SELECT i.eshopId, count(*)
from table1 as i
left join (select eshopId, count(distinct orderId) from table2 group by eshopId) j on i.eshopId=j.eshopId
WHERE i.active = TRUE
GROUP BY i.eshopId
I have 2 tables. Table A and Table B.
Table A contains the details of individual users.
Table B contains 3 columns, namely "is_completed", "user_id" and "work_id"......
Table B tracks the details of work done by users and whether the work is completed or not. If completed, then that user can be assigned another work.
Problem Statement :
I assigned a work to user 1 and his is_completed is 0 (work not finished)...now I assume that after some days, his work is finished, so I did is_completed as 1 but at the same time I assigned another work to the same user 1 and now is_completed is 0. So I have two rows of same user, one with is_completed as 1 and another is_completed as 0 in Table B.
How can I fetch the latest is_completed i.e. user 1 as working or say busy?
SELECT COUNT(DISTINCT t.work_id) AS working FROM
(
SELECT * FROM
FROM TableB
WHERE user_id = 1
ORDER BY work_id DESC LIMIT 2;
) AS t
Result:
+---------+
| working |
+---------+
| 1 | // not working
| 2 | // working
+---------+
This query will return 2 if user 1 is currently in the middle of a task, indicating that there is only one record for the most recent work_id. It will return 1 if the user has finished his previous task and has not yet received a new task, indicating two records (start and stop) for the most recent work_id.
I assume that the work_id which gets assigned is always increasing.
Like this:
select u.user_id, if(ifnull(w.is_completed, 0) = 1, 'Busy', 'Available') as Status
from users u
left join work w
on u.user_id = w.user_id
left join work w2
on w.user_id = w2.user_id and w.work_id < w2.work_id
where w2.work_id is null
Fiddle: http://sqlfiddle.com/#!9/03aa7/9
Query will return ALL users and their current availability as either 'Busy' or 'Available', depending on the status of their most recent work entry. Note this depends on the notion that work_id is an ascending, never repeating value, and that a work_id greater than another work_id, is guaranteed to be the more recent of the two.
If you want it to show the status for a specific user_id, just append AND user_id = ?? to the above query
select t.user_id,t.is_completed from( select * from
TableB
order by work_id desc )as t group by t.user_id
This will give latest work staus of a user
i have three tables on mysql database which are:
RECHARGE with these columns: rid, uid,res_id, agent_id, batch_id, rcard_order, serialno, email,
units, bankid, paydate, slipno, rpin, amtpd, bonus, description,
crSender, crSenderId,
transaction_ref,rechargeDate,
processed
SENT with these columns: sendid, uid, res_id, recipients, volume, ffdaily, message, sender, msgtype, flash, mob_field, wapurl,
date
BILL with these columns: bid, uid, email, unitBals, lastusedate
The question is these:i want a query that will subtract the sum of volume in SENT table from units in RECHARGE table and use the result to update the unitBals column on BILL table where the primary key joining the three tables is their uid.
i used this query but it is not giving me the same answer as when i sum(volume) and subtract it from sum(units) separately doing the calculation on my own
update bill set unitbals = (SELECT sum( recharge.units ) - sum( sent.volume )
FROM sent, recharge
WHERE sent.uid = recharge.uid)
where email = 'info#dunmininu.com'
There are two problems here. First, from the fact that you are using sum, I take it that there can be more than one Recharge record for a given Uid and more than one Sent record for a given Uid. If this is true, then when you do the join, you are not getting all the Recharges plus all the Sents, you are getting every combination of a Recharge and a Sent.
For example, suppose for a given Uid you have the following records:
Recharge:
Uid Units
42 2
42 3
42 4
Sent
Uid Volume
42 1
42 6
Then a query
select recharge.units, sent.volume
from recharge, sent
where recharge.uid=sent.uid
will give
Units Volume
2 1
2 6
3 1
3 6
4 1
4 6
So doing sum(units)-sum(volume) will give 18-21 = -3.
Also, you're doing nothing to connect the Uid of the Sent and Recharge to the Uid of the Bill. Thus, for any given Bill, you're processing records for ALL uids. The Uid of the Bill is never considered.
I think what you want is something more like:
update bill
set unitbals = (SELECT sum( recharge.units ) from recharge where recharge.uid=bill.uid)
- (select sum(sent.volume) from sent where sent.uid=bill.uid)
where email='info#dunmininu.com';
That is, take the sum of all the recharges for this uid, minus the sum of all the sents.
Note that this replaces the old value of Unitbals. It's also possible that you meant to say "unitbals=unitbals +" etc.
I think you need separate sum in the two tables:
update bill
set unitbals =
( SELECT sum( recharge.units )
FROM recharge
WHERE bill.id = recharge.uid
) -
( SELECT sum( sent.volume )
FROM sent
WHERE bill.id = sent.id
)
where email = 'info#dunmininu.com'