I'm trying to make a standings chart using multiple tables. One keeps tracks of meetings attended to, each meeting counting as 5 points and the other table keeps track of results of tournaments. This is a fishing club site.
I have the following so far and can show the meeting points in order but the tournament results separate from that. I'd like to find a single albeit complex SQL statement to list out current standings.
I need to show the angler name which I can grab separate from a different table, then each month's 5 points listed along with the tournament result amount from the results table, these are all added up to finally list the total from all tournaments and meetings.
SELECT aid, sum(here*5) as total
FROM rollcall GROUP BY aid ORDER BY total DESC
SELECT aid, weight, weight-penalty as fweight
FROM `results` where tid=2 order by fweight desc
So an example is:
place angler JAN FEB MARCH ... Total Points
1 name1 5 50 5 45 0 38 143
2 name2 5 49 5 47 5 31 142
...
Is that clear at all?
What if you build your query something like this?
SELECT aid,
sum(SELECT count(1) from meetings WHERE MONTH(columndatetime) = 1 * 5) AS JAN,
sum(SELECT count(1) from meetings WHERE MONTH(columndatetime) = 2 * 5) AS FEB,
/
-- add same logic to the rest of the months
/
sum(SELECT count(1) from meetings WHERE YEAR(columndatetime) = 2013 * 5) as total
FROM rollcall GROUP BY aid ORDER BY total DESC
Where columndatetime is the name of your column that has the date and time for the meetings etc...
The last one takes all for the year.
Could this help you out?
Related
I have legacy tables which tracks flight and had to extract data. We have three tables named booking, airlines and flighttype. Note this is a dummy samples
booking :
id
customer
request_date
airline
flightType
price
currency
1
1
11-20-2020 10:23
1
1
120
Eur
2
1
11-21-2020 10:24
1
2
110
CHF
3
2
11-01-2020 11:25
2
2
120
Eur
4
1
15-01-2020 10:23
1
1
100
Eur
5
1
11-01-2020 11:23
1
2
60
Eur
6
1
12-01-2020 10:23
1
3
35
Eur
airline :
id
airline
1
French
2
Swiss
type :
id
flightType
1
domestic
2
international
Now the data we are trying to figure out is number of bookings consecutively within x days (let say if two days it would mean how many bookings were made in 2 days) for various parameters like
airline
flightType
airline & flightype
currency
price total price
For example lets say I wish to see what is the percentage of customer who have made multiple bookings within x days across multiple airline I should be able to do so or if I want to see the total revenue of customers who have made multiple booking within x days or customers who have made multiple booking with different set of currencies with x days
I am trying to make self join to extract such data and then group it but I am always reaching a dead end
SELECT
t1.customer, t1.request_date, t1.airline, count(*)
FROM booking t1
JOIN booking t2
ON t1.customer= t2.customer
WHERE t2.request_date > t1.request_date and DATEDIFF(t2.request_date, t1.request_date) > 0 and DATEDIFF(t2.request_date, t1.request_date) <=2
GROUP BY t1.customer, t1.request_date
The problem I am facing is the date has time and it gives me wrong results. And I am not sure what is the right way to get %share of customers who make booking in such way like
% share of customers who book more than one flight / more than one type of flight within span of x days.
Sorry if the question is too vague or if this violates any rules.
By the way I am using mysql 5.5
I want to see the total revenue of customers who have made multiple booking within x days or customers who have made multiple booking with different set of currencies with x days
You can answer questions like this using window functions. For the first question, this looks like:
select count(distinct customer)
from (select b.*,
lag(request_date) over (partition by customer order by request_date) as prev_request_date
from booking b
) b
where request_date <= prev_request_date + interval <n> day;
I have a Mysql table with users playing as double partners in a tennis tournament and also a table with rankings in which every player has a ranking score in doubles matches.
Tournaments_registrations_doubles
id
player1_id
player2_id
1
32
25
2
25
28
3
143
83
Rankings_doubles
id
player_id
points
1
25
127
2
19
83
3
32
97
4
83
41
I am trying to build an SQL query that will get the ids of the Tournaments_registrations_doubles table in descending order based on the sum of the ranking points of each player group. So player_1 and player_2 who's sum of point in rankings table is highest should come first, and so on. Not all players are registered in the ranking table.
Any ideas on how to implement this?
Join the tournament table to the doubles table twice, once for each of the two player columns. Then order the result set descending by the sum of points.
SELECT t.id, t.player1_id, t.player2_id,
COALESCE(r1.points, 0) + COALESCE(r2.points, 0) AS total
FROM Tournaments_registrations_doubles t
LEFT JOIN Rankings_doubles r1 ON r1.player_id = t.player1_id
LEFT JOIN Rankings_doubles r2 ON r2.player_id = t.player2_id
ORDER BY COALESCE(r1.points, 0) + COALESCE(r2.points, 0) DESC;
Notice that we use left joins here, so that we may treat missing points as zero when computing the totals.
Got this table containing info about customers, dates and their purchases values.
Let's say some of them bought something in November but nothing in December.
Now, I am trying to have all the customers + all they spent and to use IFNULL() to the ones that have not bought anything in Dec. I am filtering it for Dec and all I get is the ones that purchased something in Dec, yeah... I know but I am sure there's a way how to do that but I just can't figure it out. Any help is more than welcome. Cheers
Customers Date Spent
John1 2000-11-01 12
John2 2000-11-02 33
John3 2000-11-03 13
John4 2000-11-04 24
John5 2000-11-05 36
John6 2000-12-01 55
John7 2000-12-02 16
John8 2000-12-04 33
John9 2000-12-03 18
John10 2000-12-03 13
You can enumerate the customers in a subquery, then bring the december records with a left join:
select c.customers, coalesce(sum(t.spent), 0) total_spent
from (select distinct customers from mytable) c
left join mytable t
on t.customers = c.customers
and t.date >= '2000-12-01'
and t.date < '2001-01-01'
group by c.customers
This gives you one row per customer, with their total spent in December 2000 - or 0 if they did not spent during that month.
In a real-life situation, you would typically have a separate table to store the customers, that you would use instead of the subquery.
I have a big view called: how_many_per_month
name_of_product | how_many_bought | year | month
p1 20 2012 1
p2 7 2012 1
p1 10 2012 2
p2 5 2012 2
p1 3 2012 3
p2 20 2012 3
p3 66 2012 3
How to write MySQL query in order to get only first few occurences of product p1, p2, p3 at once?
To get it one by one for first 3 months I can write:
SELECT name_of_product , sum(how_many_bought) FROM
(SELECT name_of_product, how_many_bought FROM `how_many_per_month`
WHERE name_of_product= 'p1' LIMIT 3) t
How to do it to all possible products at once so my result for taking only first month is like:
p1 20
p2 7
p3 66
For two months:
p1 30
p2 12
p3 66
The problem is that some products are published in different months and I have to make statistic how many of total of them are sold in first month, first 3 months, 6 months, 1 year divided by total.
Example using union
select
name_of_product,
sum(how_many_bought) as bought,
"first month" as period
from how_many_per_month
where month = 1
group by name_of_product
union
select
name_of_product,
sum(how_many_bought) as bought,
"first 2 month" as period
from how_many_per_month
where month <= 2
group by name_of_product
union
select
name_of_product,
sum(how_many_bought) as bought,
"first 6 month" as period
from how_many_per_month
where month <= 6
group by name_of_product
union
select
name_of_product,
sum(how_many_bought) as bought,
"first 12 month" as period
from how_many_per_month
where month <= 12
group by name_of_product
Demo: http://www.sqlfiddle.com/#!2/788ea/11
Results are different a little bit from your expectation. Are you sure that you write them properly? If you need to gain more speed in query time you can use group by case as I've already said.
I'm not quite sure what you're trying to achieve as the description of your question is a bit unclear. From what I've read so far, I understand you want to show the total of how many ITEM_X, ITEM_Y, ITEM_Z were sold for the past 1,3,6 months.
Based on the data you've provided, I've created this sqlfiddle that sums all results and groups them by item. This is the query:
SELECT
name_of_product,
sum(how_many_bought) as how_many_bought
FROM how_many_per_month
WHERE year = 2012
AND month BETWEEN 1 AND 3
GROUP BY name_of_product
-- NOTE: Not specifying an year will result in including all "months"
which are between the values 1 and 3 for all years. Remove it
in case you need that effect.
In the example above the database will sum all sold items between months 1 and 3 (including) for 2012. When you execute this query in your application just change the range in the BETWEEN X AND X and you'll be good to go.
Additional tip:
Avoid using sub-queries or try using the as a last resort method (in case there's simply no other way to do it). They are significantly slower than normal and even join queries. Usually sub-queries can be transformed into a join query.
SELECT
hmpm.name_of_product , SUM(hmpm.how_many_bought)
FROM (
SELECT name_of_product
FROM how_many_per_month
/* WHERE ... */
/* ORDER BY ... */
) sub
INNER JOIN how_many_per_month hmpm
ON hmpm.name_of_product = sub.name_of_product
GROUP BY hmpm.name_of_product
/* LIMIT ... */
MySQL not support LIMIT in subquery, but you need ordering and condition. And why not have id_of_product field?
Working in MS Access 2003 SP3: I have a query that I am running to find what 'cars' were sold with a date after the delivery date. I have thousands of rows. When it is all said and done, I want to just have a handful of rows for each 'car' and then the oldest date. Any suggestions?
CAR DATE ORDERED DATE DELIVERED CUSTOMER NUMBER DATE SOLD
FORD MUSTANG 20061002 20080413 ABC123 20080422
FORD MUSTANG 20061002 20080413 ABC124 20080429
CHEVY IMPALA 20061002 20080413 ABC125 20080505
This could be better if you had an ID field:
DELETE
FROM Cars
WHERE Cars.DATESOLD Not In (
SELECT TOP 5 DateSold
FROM Cars c
WHERE c.Car=Cars.Car
ORDER BY DateSold DESC)
And Cars.DATESOLD Not In (
SELECT TOP 1 DateSold
FROM Cars c
WHERE c.Car=Cars.Car
ORDER BY DateSold)
If there are duplicate dates, you will end up with more than 5 records.