I made a Query to get salaries and in the end a rollup to sum the result but i want to add a text 'Total'.
select which as 'Salaries', IFNULL(SUM(which1),0) as actual,IFNULL(SUM(which2),0) As estimated
from(select Type_expenses_table as which, sum(Amount_expenses_table) as which1, null as which2
From bacci.expenses_table
WHERE Date_expenses_table >= '2017-01-01'
AND Date_expenses_table < '2017-01-01' + INTERVAL 1 YEAR
AND Categories_table = 'salaries'
group by Type_expenses_table
union all
select estimated_type as which, null as which1, sum(estimated_amount) as which2
From bacci.estimated_expenses_table
Where estimated_year = '2017'
AND Categories = 'salaries'
group by estimated_type
) ae
group by which with rollup;
I want to put Total instead of null
Related
SELECT
"Fact Order Item"."product_therapy" AS "Product_therapy"
,(select sum(total_order_value_inc_tax_uc) FROM "d2c"."fact_order"
WHERE and date_created >= DATEADD(day,-7, GETDATE()) ) as "REVENUE - T7"
,(select sum(total_order_value_inc_tax_uc) FROM "d2c"."fact_order"
WHERE and date_created >= DATEADD(day,-30, GETDATE()) ) as "REVENUE - T30"
FROM "d2c"."fact_order"
LEFT JOIN "d2c"."fact_order_item" ON "d2c"."fact_order"."order_id" = "Fact Order Item"."order_id"
WHERE "d2c"."fact_order"."is_active" = '1'
GROUP BY "Fact Order Item"."product_therapy"
I'm working on a mysql request that make the sum of values by months including those with null values.
The request result send only the first line without making the sum operation.
SELECT SUM(IFNULL(t1.sub_total,0)) AS amount,
am.a_month AS date
FROM (
SELECT ifnull(vn.sub_total,0) as sub_total,
cast(DATE_FORMAT(order_date, '%M') as char) as mdate
FROM orders_new vn
WHERE order_status = 1
AND order_date BETWEEN '2022-01-01' AND '2022-12-31'
GROUP BY DATE_FORMAT(order_date, '%M')
) t1
RIGHT OUTER JOIN all_months am on t1.mdate = am.a_month
group by am.a_month
order by a_month_id asc;
result
below the source table
You don't need the GROUP BY clause in the subquery. Your query should be:
SELECT
SUM(IFNULL(t1.sub_total, 0)) AS amount,
am.a_month AS date
FROM
(SELECT
IFNULL(vn.sub_total, 0) AS sub_total,
CAST(DATE_FORMAT(order_date, '%M') AS char) AS mdate
FROM
orders_new vn
WHERE
order_status = 1
AND order_date BETWEEN '2022-01-01' AND '2022-12-31') t1
RIGHT OUTER JOIN
all_months am ON t1.mdate = am.a_month
GROUP BY
am.a_month
ORDER BY
a_month_id ASC;
I have the following query
SELECT COUNT( iContactId ) AS Users, DATE( dCreatedAt ) AS ActivityDate
FROM contacts WHERE iAppId =".$iAppId."
AND DATE(dCreatedAt) IN (CURRENT_DATE(), CURRENT_DATE()-1 )
GROUP BY ActivityDate
by this i am getting
Users |ActivityDate
1 |2014-09-19
i want 0 if there is no match rows
e.g
Users |ActivityDate
0 |CURRENT_DATE()
0 | CURRENT_DATE()-1
How can i do that.
QUERY
SELECT
COUNT(C.iContactId) AS Users,
DATE(C.dCreatedAt) AS ActivityDate
FROM
contacts C
LEFT OUTER JOIN
(
SELECT CURRENT_DATE() AS Dates FROM dual
UNION
SELECT CURRENT_DATE() - 1 AS Dates FROM dual
) D
ON
D.Dates = DATE(C.dCreatedAt)
WHERE
C.iAppId =".$iAppId."
GROUP BY
C.ActivityDate
You could use union
SELECT COUNT( iContactId ) AS Users, CURRENT_DATE() AS ActivityDate
FROM contacts WHERE iAppId =".$iAppId."
AND DATE(dCreatedAt) = CURRENT_DATE()
UNION
SELECT COUNT( iContactId ) AS Users, CURRENT_DATE() - 1 AS ActivityDate
FROM contacts WHERE iAppId =".$iAppId."
AND DATE(dCreatedAt) = CURRENT_DATE() - 1
QUERY
SELECT
ISNULL( iContactId ,0) AS Users,
DATE( dCreatedAt ) AS ActivityDate
FROM contacts
WHERE iAppId =".$iAppId."
AND DATE(dCreatedAt) IN (CURRENT_DATE(), CURRENT_DATE()-1 )
GROUP BY ActivityDate
In most answers this is used voor date substraction:
SELECT CURRENT_DATE() - 1
-> 20140919
This will result in impliciet type casting and date wil be casted to int, use this instead:
SELECT CURRENT_DATE - INTERVAL 1 DAY
-> 2014-09-19
My solution
SELECT
d.ActivityDate,
COUNT(c.iContactId) Users
FROM
(
SELECT CURRENT_DATE - INTERVAL 1 DAY ActivityDate FROM DUAL
UNION
SELECT CURRENT_DATE FROM DUAL
) d
LEFT JOIN
contacts c
ON DATE(c.dCreatedAt) = d.ActivityDate
AND c.iAppId = " . $iAppId . "
GROUP BY d.ActivityDate
I have the following query that gets some results I would like to group by attribute 'state'.
I tried different subquery but they didn't work and I'm a bit blocked.
The SQL is:
SELECT state, id_candidate_basic, MAX( DATE ) FROM `candidate_state`
WHERE `date` <= '2013-09-06 00:00:00' GROUP BY id_candidate_basic
ORDER BY `candidate_state`.`id_candidate_basic` DESC
This returns currently:
I would get a count(*) for each state. Example:
F, 14
I, 10
O, 9
SELECT state,
id_candidate_basic,
MAX( DATE ),
COALESCE(totalCount, 0) totalCount
FROM `candidate_state`
LEFT JOIN
(
SELECT state, COUNT(*) totalCount
FROM candidate_state
WHERE `date` <= '2013-09-06 00:00:00'
GROUP BY state
) ON candidate_state.state = b.state
WHERE `date` <= '2013-09-06 00:00:00'
GROUP BY id_candidate_basic
ORDER BY `candidate_state`.`id_candidate_basic` DESC
Hi all i execute this query to get a table where there's statistics of some database information.. i'd like to intialise the fields that don't exist ( because the query is executed in different dates and sometimes there's a day where there's nothing ) so i'd like it to return 0 and NULL ( in TOP column )
SELECT
SUM(IF(`TOP` = 'one',`Nb`,0)) as first_one,
SUM(IF(`TOP` = 'two',`Nb`,0)) as second_one,
SUM(IF(`TOP` = 'three',`Nb`,0)) as thrid_one,
SUM(IF(`TOP` NOT IN ('three','two','one'),`Nb`,0)) as forth_one,
GROUP_CONCAT(IF(`TOP` NOT IN ('three','two','one'),`TOP`,'') SEPARATOR '') as `OR`
FROM (
SELECT
COUNT(*) as Nb,
'one' as `TOP`
FROM
mytable
WHERE
TYPE = 'MSS'
AND YEAR(date) = YEAR(CURDATE())
AND MONTH(date) = MONTH(CURDATE())
UNION ALL
SELECT
COUNT(*) as Nb,
'two' as `TOP`
FROM
mytable
WHERE
TYPE = 'MSS'
AND S=0
AND YEAR(date) = YEAR(CURDATE())
AND MONTH(date) = MONTH(CURDATE())
UNION ALL
SELECT
COUNT(*) as Nb,
'three' as `TOP`
FROM
mytable
WHERE
TYPE = 'MSS'
AND S<>0
AND YEAR(date) = YEAR(CURDATE())
AND MONTH(date) = MONTH(CURDATE())
UNION ALL
SELECT
`Nb`,
`TOP`
FROM(
SELECT
COUNT(*) as Nb ,
`OR` as `TOP`
FROM
mytable
WHERE
TYPE = 'MSS'
AND YEAR(date) = YEAR(CURDATE())
AND MONTH(date) = MONTH(CURDATE())
GROUP BY
`OR`
ORDER BY
Nb DESC
LIMIT 1
) as tmp
)as tmp1
Assuming that in tmp1 you have data you need but with "gaps" (days when there were no data at all) you could RIGHT JOIN tmp1 to table tmp2 using day (I assume that you have such column in tmp1 table). So tmp2 would be just list of days:
SELECT '2013-05-17' as day UNION SELECT '2013-05-18' UNION SELECT ...
I could elaborate my answer if you'd like to provide your DB schema.
You can replace each subquery with:
SELECT
IFNULL(tmp.Nb,0) as Nb,
IFNULL(tmp.`TOP`, 'value') as `TOP`
FROM (
--subquery
) as tmp
Example for the first subquery:
SELECT
IFNULL(tmp.Nb,0) as Nb,
IFNULL(tmp.`TOP`, 'one') as `TOP`
FROM (
SELECT
COUNT(*) as Nb,
'one' as `TOP`
FROM
mytable
WHERE
TYPE = 'MSS'
AND YEAR(date) = YEAR(CURDATE())
AND MONTH(date) = MONTH(CURDATE())
) as tmp
SQL is good at grouping existing entities into categories, but bad at "creating" entities itself. I would advise either a generic number table (really just the numbers from 0 to a few hundredthousand) if you have also non-date categories or as Wiktor suggested a date-Table which gets filled every now and then and has the next few years as well as the time since your program is working.
With a date table
list_dates (
id int(11) not null primary key auto_increment,
dateval date not null
)
you could start your queries from that table (with a reasonable range, of course) and count every thing else:
select list_dates.dateval as date, count(*) as cnt
from list_dates
left join actions on actions.actiontime >= (cast list_dates.date_val as datetime)
and actions.actiontime < (cast list_dates.date_val `interval 1 day as datetime)
where list_dates.dateval between '$fromDate' and '$toDate'
group by list_dates.dateval
;
or starting with a number table numbers
select $fromDate + interval numbers.number day as date, count(*) as cnt
from numbers
left join actions
on actions.actiontime >= (cast $fromDate + interval numbers.number day as datetime)
and actions.actiontime < (cast $fromDate + interval (1 + numbers.number) day as datetime)
where numbers.number >= 0 and numbers.number < $countDates
group by numbers.number
;
One Day
If you really want just that one day (today) then you can of course use a anonymous subselect- Table instead, so it becomes
select list_dates.dateval as date, count(*) as cnt
from ( select curdate() as dateval ) as list_dates
left join actions on actions.actiontime >= (cast list_dates.date_val as datetime)
and actions.actiontime < (cast list_dates.date_val `interval 1 day as datetime)
where list_dates.dateval between '$fromDate' and '$toDate'
group by list_dates.dateval
;