find newest billings unpaid [closed] - mysql

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a MySQL table of billing records. Each entry records either a payment or a charge, the amount, the date applied, and the related customer id. If there are more charges than payments, how can I get the outstanding charge records sorted by most recent, and if there are more payments than charges, the payment credits sorted by most recent? Basically, if I have 3 rows of charges amounting to $1.25 each, and 2 rows of $1.50, how can I get the 3 charge record that is the most recent, and know that there is only $0,75 left due? I hope that makes sense.
Let's say we have this table:
user_id | amount | date_applied | type
---------------------------------------
1 1.25 *datetime* -
1 1.25 *datetime* -
1 1.25 *datetime* -
1 1.50 *datetime* +
1 1.50 *datetime* +
the result should be something similar to this:
user_id | amount | date_applied | type
---------------------------------------
1 0.75 *datetime* -
I may not even be thinking about this right. I am open to other suggestions

Your question is a bit tricky. That's because there is no clear definition on what datetime to show. It seems you want to have the sum of all positive and negative values on the table per user. The problem is that when you make a total you can't have a detail of the datetimes. You will have to choose one of them, but there won't be any order in the result as there will only be one datetime per user in the result (in your example you can see for user 1 there is only one datetime).
Also, do you need the type column? Why not add it to the amount?
This is the closest I can get to your needs given the detail provided:
select user_id, sum(if(type = '+', amount, -amount)) amount from t
group by user_id
+---------+--------+
| USER_ID | AMOUNT |
+---------+--------+
| 1 | -0.75 |
+---------+--------+
Note: If you really need the datetime put a real date for each record and update the expected result with the expected date value.

SELECT
A.USERID,
B.TOTAL,
A.date_applied,
IF(B.TOTAL < 0, '-', '+')
FROM
TABLE AS A
JOIN
(
SELECT
USERID,
SUM(IF(TYPE = '+', AMOUNT, AMOUNT * -1)) AS TOTAL
FROM
TABLE
GROUP BY
USERID, AMOUNT
) AS B
ON A.USERID = B.USERID

Related

SQL queries for calculating shipping charges based on subtotal amount [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
ID
Name
min_amount
charge
1
Standard
50.00
3.00
2
Express
50.00
5.00
3
Standard
100.00
2.00
4
Express
100.00
0.00
so I have this table in SQL and my requirement is to calculate shipping based on min_amount (subtotal). for eg: if the subtotal is 45.00 I want to get the row with ID 1,2 (because 45.00 < 50.00). and similarly if subtotal is 55 it should be the row with ID 3,4.
SELECT id,min_amount, MAX(charge) as shipping FROM `shippings` WHERE min_amount > 45.00 GROUP BY name
this is working. but when the value changes to 101.00, this returns nothing I want it to return the max min_amount row which is 3,4
what should I change? and what is the eloquent query for this, since I'm using laravel but can be done without it.
You need to get the highest min amount value first and use it to make a decision on upper value using IF condition in WHERE clause,
SELECT id, name, min_amount, MAX(charge) as shipping
FROM shippings,
(SELECT MAX(min_amount) as min_amount_limit FROM shippings) z
WHERE min_amount >= IF(z.min_amount_limit < 101.00, z.min_amount_limit, 101.00)
GROUP BY name;
Working Fiddle

Custom Sort Order for MYSQL Count Results?

I am trying to write a report on some data I collected using a google form. Each person was asked how many of an item they had in their closet. I want to present the data as a count of how many out of the total fell into each range. So, I used this mysql query to count the instances of each answer:
SELECT `Closet` , COUNT( * ) FROM `TABLE 1` GROUP BY `Closet`
And here is the resulting data:
Closet | COUNT( * )
--------+------------
0 | 8
1-5 | 124
101-200 | 7
11-20 | 181
201-300 | 3
21-50 | 171
51-100 | 48
6-10 | 156
The problem is that alphabetically, 101-200 items sorts before 6-10 items. I basically want to sort this in some way that would put the number ranges in a logical order. (1-5, 6-10, 11-20, etc).
How can I accomplish this?
You'll have to use convert & substring_index.
SELECT `Closet` , COUNT( * ) FROM `TABLE 1` GROUP BY `Closet` order by convert(substring_index(Closet,'-',1), unsigned integer)
This will sort the Closet by taking the first number of the ranges, which should essentially do the job.

MySQL - Select row with column + X > column

We have a database for patients that shows the details of their various visits to our office, such as their weight during that visit. I want to generate a report that returns the visit (a row from the table) based on the difference between the date of that visit and the patient's first visit being the largest value possible but not exceeding X number of days.
That's confusing, so let me try an example. Let's say I have the following table called patient_visits:
visit_id | created | patient_id | weight
---------+---------------------+------------+-------
1 | 2006-08-08 09:00:05 | 10 | 180
2 | 2006-08-15 09:01:03 | 10 | 178
3 | 2006-08-22 09:05:43 | 10 | 177
4 | 2006-08-29 08:54:38 | 10 | 176
5 | 2006-09-05 08:57:41 | 10 | 174
6 | 2006-09-12 09:02:15 | 10 | 173
In my query, if I were wanting to run this report for "30 days", I would want to return the row where visit_id = 5, because it's 28 days into the future, and the next row is 35 days into the future, which is too much.
I've tried a variety of things, such as joining the table to itself, or creating a subquery in the WHERE clause to try to return the max value of created WHERE it is equal to or less than created + 30 days, but I seem to be at a loss at this point. As a last resort, I can just pull all of the data into a PHP array and build some logic there, but I'd really rather not.
The bigger picture is this: The database has about 5,000 patients, each with any number of office visits. I want to build the report to tell me what the average wait loss has been for all patients combined when going from their first visit to X days out (that is, X days from each individual patient's first visit, not an arbitrary X-day period). I'm hoping that if I can get the above resolved, I'll be able to work the rest out.
You can get the date of the first and next visit using query like this (Note that this doesn't has correct syntax for date comparing and it is just an schema of the query):
select
first_visits.patient_id,
first_visits.date first_date,
max(next_visit.created) next_date
from (
select patient_id, min(created) as "date"
from patient_visits
group by patient_id
) as first_visits
inner join patient_visits next_visit
on (next_visit.patient_id = first_visits.patient_id
and next_visit.created between first_visits.created and first_visits.created + 30 days)
group by first_visits.patient_id, first_visits.date
So basically you need to find start date using grouping by patient_id and then join patient_visits and find max date that is within the 30 days window.
Then you can join the result to patient_visits to get start and end weights and calculate the loss.

MySQL, incrementing a row count by ascending dates (simple?)

I normally work in Access but cannot figure this logic within it. I'm now branching to MySQL in hopes i can do this.
Have table Visits with CUSTOMERID, VISITDATE
CUSTOMERID VISITDATE
1001 7/6/2015
2315 9/1/2015
2315 12/30/2014
9851 5/5/2013
9851 1/7/2014
9851 3/21/2014
I'd like to add a column called 'Visit Number' so I can label in ascending order each Customer's visitdate as his first, second, etc...
It would look like:
CUSTOMERID VISITDATE VISITNUMBER
1001 7/6/2015 1
2315 9/1/2015 1
2315 12/30/2014 2
9851 5/5/2013 1
9851 1/7/2014 2
9851 3/21/2014 3
It's an incrementation based on the ascending dates, but also grouped by CUSTOMERID.
Would seriously appreciate any tips on this. Thanks.
OK. So you have a query that you use to update your date whenever someone visits.
You want to cause an additional action at this point because this equates to an increment of visits.
if I'm not incorrect, a simple bundle of:
YOUR UPDATE SQL;
UPDATE mytable
SET visitnumber = visitnumber + 1
WHERE customerid = (the id of the user you are updating);

finding most 'popular' items in multiple tables in mySQL [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have multiple tables of items which are 'ordered' by their ratings/popularity.
I need to combine all the tables into one table with a top 10.
The top 10 will combine the number of times an entry (with wildcard as the names may be slightly different) appears in all the lists and it's position in the tables.
is this possible?
I've researched Joins but it seems quite a complicated procedure given there are two factors (nubmer of entries and position in the tables).
Apologies for being vague, I didn't think I was doing so. This is my first question on stackoverflow
table 1 table 2 table 3
--------------------
bob | bob | Ian
fred | james |john
kate | fred | bob
mary | brian | brian
the 'rankings' results of the three tables need to appear in a final table (called 'final' for example)
As you can see Bob would rank highly on 'final'.
But Ian appears only once, even though he is top of the list in table 3.
Fred appears in position 2 and position 3 so should he be higher or lower than Ian.
would I need an algorithm for the sorting or is there some trick in mySQl that will examine the rankings?
You can return them with a ranking, but you need to define how that rank applies.
For example if you just return the ranking from each table then Bob appears twice in the first position. If you add those 2 ranks together it gives 2. How do you compare that to Ian who is only ranked 1 once.
For this you are probably best building a ranking from the last row (or calculating it as total number of rows - ranking).
You can get a basic ranking from each table with the following:-
SELECT some_name, #rank_1:=#rank_1 + 1 AS ranking
FROM table_1
CROSS JOIN (SELECT #rank_1:=0) sub_1
UNION ALL
SELECT some_name, #rank_2:=#rank_2 + 1 AS ranking
FROM table_2
CROSS JOIN (SELECT #rank_2:=0) sub_2
UNION ALL
SELECT some_name, #rank_2:=#rank_2 + 1 AS ranking
FROM table_2
CROSS JOIN (SELECT #rank_2:=0) sub_3
but this will give you each record from each table and their ranking.
As it is though, you have nothing to say that Bob is the first record on table_1. While it may be the first record, as far as the order returned this is not a certainty.