Mysql filling in missing dates - mysql

I have the following query
SELECT *
FROM attend
RIGHT OUTER JOIN noattend ON attend.date = noattend.date2
WHERE attend.date
BETWEEN '2010-02-01'
AND '2010-04-01'
AND attend.customerid =1
ORDER BY date DESC
LIMIT 0 , 30
Attend is the table with customerid
noattend is the table with a row for each date (date2) I followed the advice in other questions to right outer join it to create values where there is no record in attend but it still isn't filling in the empties
any help much appreciated

If you say that noattend is a table with a row for each date, you should use it in WHERE clause:
WHERE noattend.date2 BETWEEN (.....
And I think it's more clear to use LEFT JOIN :
SELECT *
FROM noattend
LEFT OUTER JOIN attend ON (attend.date = noattend.date2 AND attend.customerid =1)
WHERE noattend.date2
BETWEEN '2010-02-01'
AND '2010-04-01'
ORDER BY date DESC
LIMIT 0 , 30

You need to get rid of the SELECT * and list your column names instead. Where you want the date to be, use the field noattend.date2, not attend.date. Attend.date will be NULL (blank) for those extra rows created to fill in your "missing" dates.
Something like:
SELECT attend.id, attend.name, noattend.date2
FROM . . . (continue your code here)

Related

How to create a SQL ordering based on JOIN values and on today month

I have two databases
TABLE_ORDERS with id,created,user_id.....status_id
TABLE_STATUSES with it,title,ordering,month
ordering is an integer for ordering statuses and month is the month number (01-January, 02-February, ...)
I would like to create somethig like:
SELECT *
FROM TABLE_ORDERS,
TABLE_STATUSES
WHERE 1
AND TABLE_STATUSES.month >= '7'
ORDER BY TABLE_STATUSES.ordering
What should be the right syntax?
The wished result is a table of orders ordered by statues like "To be delivered on January, To be delivered on February" that will change automatically month by month.
Thank you for your support!
I think you should try
Select * from TABLE_ORDERS o inner join TABLE _STATUSES s ON o.id=s.id WHERE MONTH(s.month)>=7 ORDER BY s.ordering.
You can filter out months gretter than 7.
Good luck.
your query can go like this :
SELECT TABLE_ORDERS.*, TABLE_STATUSES.month
FROM TABLE_ORDERS INNER JOIN TABLE_STATUSES
ON TABLE_STATUSES.id = TABLE_ORDERS.status_id
ORDER BY TABLE_STATUSES.ordering
An example can be :
SELECT column_list
FROM table_1
INNER JOIN table_2 ON table_1.columnname = table_2.columnname;

Conditionally counting while also grouping by

I am trying to join two tables
ad_data_grouped
adID, adDate (date), totalViews
This is data that has already been grouped by both adID and adDate.
The second table is
leads
leadID, DateOfBirth, adID, state, createdAt(dateTime)
What I'm struggling with is joining these two tables so I can have a column that counts the number of leads when it shares the same adID and where the adDate = createdAt
The problem I'm running into is that when the counts are all the same for all groupings of adID....I have a few other things I'm trying to do, but it's based on similar similar conditional counting.
Query:(I know the temp table is probably overkill, but I'm trying to break this up into small pieces where I can understand what each piece does)
CREATE TEMPORARY TABLE ad_stats_grouped
SELECT * FROM `ad_stats`
LIMIT 0;
INSERT INTO ad_stats_grouped(AdID, adDate, DailyViews)
SELECT
AdID,
adDate,
sum(DailyViews)
FROM `ad_stats`
GROUP BY adID, adDate;
SELECT
ad_stats_grouped.adID,
ad_stats_grouped.adDate,
COUNT(case when ad_stats_grouped.adDate = Date(Leads.CreatedAt) THEN 1 ELSE 0 END)
FROM `ad_stats_grouped` INNER JOIN `LEADS` ON
ad_stats_grouped.adID = Leads.AdID
GROUP BY adID, adDate;
The problem with your original query is the logic in the COUNT(). This aggregate functions takes in account all non-null values, so it counts 0 and 1s. One solution would be to change COUNT() to SUM().
But I think that the query can be furtermore improved by moving the date condition on the date to the on part of a left join:
select
g.adid,
g.addate,
count(l.adid)
from `ad_stats_grouped` g
left join `leads` l
on g.adid = l.adid
and l.createdat >= g.addate
and l.createdat < g.ad_stats + interval 1 day
group by g.adid, g.addate;

Getting all value from every month, put zero if no data of that month

i'm trying to get data for each month, if there is no data found for a particular month, I will put zero. I already created a calendar table so I can left join it, but I still can't get zero.
Here's my query
SELECT calendar.month, IFNULL(SUM(transaction_payment.total),0) AS total
FROM `transaction`
JOIN `transaction_payment` ON `transaction_payment`.`trans_id` =
`transaction`.`trans_id`
LEFT JOIN `calendar` ON MONTH(transaction.date_created) = calendar.month
WHERE`date_created` LIKE '2017%' ESCAPE '!'
GROUP BY calendar.month
ORDER BY `date_created` ASC
the value in my calendar tables are 1-12(Jan-Dec) int
Result should be something like this
month total
1 0
2 20
3 0
4 2
..
11 0
12 10
UPDATE
The problem seems to be the SUM function
SELECT c.month, COALESCE(t.trans_id, 0) AS total
FROM calendar c
LEFT JOIN transaction t ON month(t.date_created) = c.month AND year(t.date_created) = '2018'
LEFT JOIN transaction_payment tp ON tp.trans_id = t.trans_id
ORDER BY c.month ASC
I tried displaying the ID only and it's running well. but when I add back this function. I can only get months with values.
COALESCE(SUM(tp.total), 0);
This fixes the issues with your query:
SELECT c.month, COALESCE(SUM(tp.total), 0) AS total
FROM calendar c LEFT JOIN
transaction t
ON month(t.date_created) = month(c.month) AND
year(t.date_created) = '2017' LEFT JOIN
transaction_payment tp
ON tp.trans_id = t.trans_id
GROUP BY c.month
ORDER BY MIN(t.date_created) ASC;
This will only work if the "calendar" table has one row per month -- that seems odd, but that might be your data structure.
Note the changes:
Start with the calendar table, because those are the rows you want to keep.
Do not use LIKE with dates. MySQL has proper date functions. Use them.
The filtering conditions on all but the first table should be in the ON clause rather than the WHERE clause.
I prefer COALESCE() to IFNULL() because COALESCE() is ANSI standard.
You need to use right as per your query because you calendar table is present at right side
SELECT calendar.month, IFNULL(SUM(transaction_payment.total),0) AS total
FROM `transaction`
JOIN `transaction_payment` ON `transaction_payment`.`trans_id` =
`transaction`.`trans_id`
RIGHT JOIN `calendar` ON MONTH(transaction.date_created) = calendar.month
WHERE`date_created` LIKE '2017%' ESCAPE '!'
GROUP BY calendar.month
ORDER BY `date_created` ASC

MySQL Query needs to bring back rows, not empty results

OK, I've voted to delete my earlier question due to stupidity on my part...
I have the following code:
SELECT qnum, id, name, total_staff AS StaffCount, COUNT( q61g ) AS TotalResp,
(COUNT( q61g ) / total_staff * 100) AS Perc
FROM tdemog_pfp
LEFT JOIN tresults_pfp ON tdemog_pfp.id = tresults_pfp.q61g
WHERE qnum = 'q61g' AND q60p = '1'
GROUP BY name
ORDER BY name
Now, the first part of this query brings back rows from the tdemog table, for example it will bring back 5 rows of data each row has an id from 1 to 5. What I need the query to do is then bring back data from the tresults table WHERE q60p = 1 for each of the 5 rows brought back in the first part - like a normal `LEFT JOIN'.
Make sense?
H.
Try moving part of your WHERE clause into your JOIN condition:
SELECT ...
FROM tdemog_pfp
LEFT JOIN tresults_pfp ON tdemog_pfp.id = tresults_pfp.q61g AND q60p = '1'
WHERE qnum = 'q61g'
GROUP BY name
ORDER BY name
If you have a field from your second table in your WHERE clause, it will restrict the entire record... but if you put it into your JOIN condition, the record from the first table should still be returned even when the record in the second table doesn't meet the additional criteria...
I'm not sure which column belongs to which table... but move whatever columns are in your second table into your JOIN.

how do i get the number of members on status name

I have a member Table with member_Id
a mmship table with columns mmshipstart date and member_Id and mshipstatus_Id
another table mshipstatustype with columns mshipstatus_Id and mshipstatus_name
I have got mshipstatus_name row value is prospective......
how do i get the number of members(count) per month those are having mshipstatusname is prospective
can i get the count starting from mmshipstart date .
would any one help me out...
I am new to joins would any one pls help....
The following should do the trick:
SELECT COUNT(*)
FROM member inner join mmship
ON member.member_Id = mmship.member_Id
INNER JOIN mshipstatus
ON mshipstatus.mshipstatus_Id = mmship.mshipstatus_Id
WHERE mshipstatus.mshipstatusname = 'prospective'
AND MONTH(mmship.mmshipstart_date) = MONTH(GETDATE())
(you can change the getdate() with another date).
Does
select count(*) as prospective from mshipstatustype t1 join mmship t2 where
t1.mshipstatus_id=t2.mshipstatus_id and t2.mshipstatus_name="prospective" group by
year(mmshipstart_date), month(mmshipstart_date)
Do what you want?