SUM CASE , sum all value in when instead of just 1 - php

$scoreboard->selectRaw("SUM(CASE WHEN tgl IN ($dateFormat) THEN score ELSE 0 END) AS '$day'");
In this code column tgl will check if there is the same value in $dateFormat and if so it will then sum table score. $dateFormat is like this '2022-12-01', '2023-01-01', '2023-02-01', the problem with this is an OR so they just check if the same value in tgl exist in those 3 value and if it find it in one of them it will just end.
Is there a way to reformat the query where it would sum the score of those 3 date ?
And could i have the same AS $day Name ? like AS Day1 in two queries would the 2nd query add the data to the 1st one ?
Example :
Name
tgl
score
A
2022-12-01
100
A
2022-12-01
200
A
2022-12-01
300
A
2022-12-02
400
A
2022-01-01
100
A
2022-01-01
100
A
2022-01-03
200
A
2022-02-01
100
A
2022-02-01
200
A
2022-02-02
300
Output :
Name
Day 1
Day 2
Day 3
A
600 (sum of 2022-12-01)
400 (sum of 2022-12-02)
0 (cause theres no value in this date)
A
100 (sum of 2022-01-01)
0 (cause theres no value in this date)
200 (sum of 2022-01-03)
A
300 (sum of 2022-02-01)
300 (sum of 2022-02-02)
0 (cause theres no value in this date)
Something like this what iam looking for
sorry bad english

You should use GROUP BY instead of CASE WHEN.
Final SQL will be like SELECT tgl, name, SUM(score) FROM tableName GROUP BY tgl, name;.
Without testing, try this:
DB::table("tableName")->select("tgl", "name")->selectRaw("SUM(score)")->groupBy("tgl", "name")->get();

Related

show the beginning balance and ending balance based on date selected PHP mysqlquery

I changed my transaction to one single table. How can I show the beginning balance in and ending balance based on the date selected.
Here's my new Transaction table.
TBL NAME: transaction_history
trans_itemdesc
trans_qtyin
trans_wtin
trans_datein
trans_qtyout
trans_wtout
trans_dateout
status
Item1
500
5000
2020-11-01
Item2
300
3000
2020-11-25
Item1
200
2000
2020-11-01
Item1
50
2020-11-11
Item2
25
2020-11-31
OPEN
Item1
40
2020-11-31
OPEN
Item1
100
2020-11-04
OPEN
Desired output as of November
Product
BegBal
In
Out
EndBal
Item1
0
700
140
560
Item2
0
300
25
275
Output on the next MOnth
Product
BegBal
In
Out
EndBal
Item1
560
0
0
660
Item2
275
0
0
275
The beginning balance should carry the ending balance for the next month.
You really should just have one table; separate in and out tables make more problems than they solve. Guessing at some of your column names, I suspect you don't really have a column named 'Date Out' etc
select product as Product,
coalesce(sum(case when dt < '2020-12-01' then amount end),0) as BegBal,
coalesce(sum(case when dt between '2020-12-01' and '2020-12-31' and type='in' then amount end),0) as In,
coalesce(sum(case when dt between '2020-12-01' and '2020-12-31' and type='out' then -amount end),0) as Out,
coalesce(sum(case when dt <= '2020-12-31' then amount end),0) as EndBal
from (
select 'in' as type, product, date_in as dt, in as amount from in
union all
select 'out' as type, product, date_out, -amount from out
) in_out;

Manipulate Date, new day starts at specific time SQL

I'm developping a dashboard for a restaurant/bar.
I want to manipulate the date , so for example:
If they sell something at 02 january ,01h30 .
This amount should be added to the amount of the 1st January and not to the amount of the 2nd January.
So basically on the next day from 00h00 until 03h59, the amount that they sell, should be added to the previous date.
At the moment my SQL query just displays both dates but I want it grouped in 1 date. If this isn't possible with SQL, I have my dashboard in PHP, so I can eventually manipulate it in PHP if anyone could provide me that info.
My query
select CONVERT(CHAR(10), receiptdatetime, 120), datename(DW,receiptdatetime),
sum(rld.NetAmount), count(rl.ReceiptId)
from receipt r, receiptline rl, vw_ReceiptLineDetail rld
where rl.ReceiptId = r.ReceiptId and
rl.ModifiedKind != 300
and rld.ReceiptLineId = rl.ReceiptLineId and
receiptdatetime <= DATEADD(HOUR,4,DATEADD(DAY,1, '01/01/2018'))
and receiptdatetime >= DATEADD(HOUR,4,'01/01/2018')
group by CONVERT(CHAR(10), receiptdatetime, 120), datename(DW, receiptdatetime)
order by 1
So the current output is like this (shortened):
Date Amount
1 01/01/2018 100
2 02/01/2018 20
But I want it like this
Date Amount
1 01/01/2018 120
You can use this query and work with dates as you want
here is you first query that gives you that result
select CONVERT(CHAR(10), receiptdatetime, 120), datename(DW,receiptdatetime),
sum(rld.NetAmount), count(rl.ReceiptId)
from receipt r, receiptline rl, vw_ReceiptLineDetail rld
where rl.ReceiptId = r.ReceiptId and
rl.ModifiedKind != 300
and rld.ReceiptLineId = rl.ReceiptLineId and
receiptdatetime <= DATEADD(HOUR,4,DATEADD(DAY,1, '01/01/2018'))
and receiptdatetime >= DATEADD(HOUR,4,'01/01/2018')
group by CONVERT(CHAR(10), receiptdatetime, 120), datename(DW, receiptdatetime)
order by 1
you can use this result as a first select with this :
With CTE as
(
select CONVERT(CHAR(10), receiptdatetime, 120), datename(DW,receiptdatetime),
sum(rld.NetAmount), count(rl.ReceiptId)
from receipt r, receiptline rl, vw_ReceiptLineDetail rld
where rl.ReceiptId = r.ReceiptId and
rl.ModifiedKind != 300
and rld.ReceiptLineId = rl.ReceiptLineId and
receiptdatetime <= DATEADD(HOUR,4,DATEADD(DAY,1, '01/01/2018'))
and receiptdatetime >= DATEADD(HOUR,4,'01/01/2018')
group by CONVERT(CHAR(10), receiptdatetime, 120), datename(DW, receiptdatetime)
order by 1
)
so like this you have the result stored on a table called CTE
NOw i don't have the data so i will create my owne Variable table to store the result that you got from first query you can use your CTE tabale as a source instade of #Table
Declare #Table table (
id int,
dates date,
amout int
)
insert into #Table
select 1 , '2018-01-01' , 100 union
select 2 , '2018-01-02' , 20 union
select 2 , '2018-02-02' , 200 union
select 2 , '2018-01-03' , 20 union
select 2 , '2018-01-04' , 20
now to get the Amout with the result that you want here is the query to use
you do the select from CTE :
select sum(amout) as Amout from #Table
where dates between '2018-01-01' and '2018-01-04'
Result :
Amout
160
now you will use that result and union it with you table to get the ID that you want and the date that you want and i thing you should convert the last table date into nvarchar(50) so you will have this result
1- when you do the whole month
ID Date Amout
1 2018-01 160
2- when you do by timeframe
ID Date Amout
1 '2018-01-01 2018-01-14' 160
you can start by hardcoding the ID and Date as you want and union is to the result Amout that you get from the query
or you can do variables to configure the ID and date that you want to show with the Amout
thanks if you ahve any questions i'm here i have done the test on my local and it works and i hope that this is what you need :)
use the :
;With CTE as ( select (RowCount() Over (Partition by Date order by id) row_count) , date, amout
from tables and where conditions
Then on the select Add the amount that have the same Date into each others
selecting from CTE table
if you want to Add the Amounts of all day on the same month then select Only Year and Month on Date column then do the partition by over this Date

Is it possible to loop the result of a query that gets each revenue for the last 8 weeks based on the input date of the user?

User input = '2017-03-12'
Let say I have this tableRevenue
date revenue
---------- ---------
2017-01-01 100
2017-01-08 100
2017-01-15 100
2017-01-22 100
2017-01-29 100
2017-01-05 100
2017-01-12 100
2017-02-19 100
2017-02-26 100
2017-03-05 100
2017-03-12 100
And another tableHolidays which contains
date
----------
2017-01-15
2017-02-19
2017-03-05
I want to display it like this:
date revenue
---------- ---------
2017-01-01 100
2017-01-08 100
2017-01-22 100
2017-01-29 100
2017-01-05 100
2017-01-12 100
2017-02-26 100
2017-03-12 100
I want to display the revenue each of the last 8 weeks and I want to skip all the dates that are existing in tableHolidays using a loop. Is this possible in PHP?
mention: you didn't tag any specific database - my answer will refer to SQL-Server:
assuming #UserDate is a variable with the user input date
Use Date-Functions (specific to every DB system) to calculate the date range. in your case to subtract the 8 weeks.
Select all rows within this date range
exclude (NOT IN) all dates from your resultset which occur in your tableHolidays table
GROUP BY weeks (calculate weeknumber with WEEK) and SUM the revenue
Query:
SELECT WEEK(tR.date) as weeknr
,SUM(tR.revenue)
FROM tableRevenue tR
WHERE tR.date >= DATEADD(wk,-8,#UserDate)
AND tR.date <= #UserDate
AND tR.date NOT IN (SELECT date FROM tableHolidays)
GROUP BY WEEK(tR.date)
you can use the 'ANY' which is a mysql operator
for more information you can visit this link
https://www.w3schools.com/sql/sql_any_all.asp
$userInput = '2017-03-12';
$sql = "SELECT `date`, `revenue`
FROM `tableRevenue`
WHERE (
(`date` = ANY
(SELECT `date` FROM `tableHolidays` WHERE DATE(date)<='{$userInput}'))
AND (DATE(date) <='{$userInput}')
)";

Mysql Query for counting rows with specific days difference

Going to make a line graph. I want to query count with difference of 5 days.
Suppose if I have following rows:
booking_date
2015-02-1
2015-02-3
2015-02-5
2015-02-6
2015-02-6
2015-02-9
2015-02-10
2015-02-15
2015-02-17
2015-02-23
2015-02-28
In above table column it contains date. Now How can I do mysql query so that it can return with difference of 5 days like:
1 => 3 // count of date between 2015-02-1 & 2015-02-05 is 3
2 => 4 // count of date between 2015-02-06 & 2015-02-10 is 4
3 => 1 // count of date between 2015-02-11 & 2015-02-15 is 1
4 => 1 // count of date between 2015-02-16 & 2015-02-20 is 1
5 => 1 // count of date between 2015-02-21 & 2015-02-25 is 1
6 => 1 // count of date between 2015-02-26 & 2015-02-30 is 1
Is any direct way to query like above. I am not so good at mysql. But can do php nicely.
You can do the following to get everything in the same query.
First of all get the unix timestamp for the date you want to start grouping in 5 days. In your example that would be 2015-02-01 -> 1422748800
Then the query would be the following:
SELECT COUNT(*), FLOOR((UNIX_TIMESTAMP(booking_date) - 1422748800)/ (60*60*24*5)) as FiveDayPackNumber from tbl GROUP BY FLOOR((UNIX_TIMESTAMP(booking_date) - 1422748800)/ (60*60*24*5))
Haven't tested it so it may require some tweaking but you can get the idea: It will group them by the number of 5-days-packs that passed since your initial date, starting at 0.
Do you mean to do something like:
SELECT COUNT(1) FROM {table_name} WHERE booking_date > 2015-02-01 AND booking_date < 2015-02-05
?
(completely off memory so you might need to slightly alter it)
SELECT count(*)
FROM tbl
WHERE booking_date >= start_date
AND booking_date <= end_date

How to get the sum of values by month vice using mysql

I would like to get sum of total price from the below tables by month from to month to .Example : Jan to Mar How to get the name of the month as well sum of the particular month total. I totally confused with this.Anyone please help me. I'm passing the input like '04-2014' to '05-2014'
Sale table
id_sale date time
1 2014-05-05 12.30 am
2 2014-05-06 10.30 am
3 2014-05-25 12.30 am
Sale Product table
id_sale_product id_sale price quantity id_product
1 1 10.00 1 1
2 1 20.00 1 2
3 2 20.00 3 5
4 3 20.00 4 6
I want to filter by date in sale table and get the sum of the price * quantity = total for every date ie,2014-05-05,2014-05-06..etc
I have tried below query
$query = 'SELECT sp.`id_product_type`,sp.`id_product`,sp.`quantity`,sp.`price`,s.`date`,SUM(sp.`price` * sp.`quantity`) AS total
FROM `'._DB_PREFIX_.'sale_product` sp
LEFT JOIN '._DB_PREFIX_.'sales s ON (sp.id_sale = s.id_sale)
WHERE DATE_FORMAT(s.`date`, "%m-%Y") BETWEEN "'.$monthFrom.'" AND "'.$monthTo.'"';
The output should be :
Example: Month
January Rs. 2,00,000
Feburary Rs. 2,20,000
This query should help:
SELECT DATE_FORMAT(s.date, "%M-%Y"),SUM(sp.`price` * sp.`quantity`) AS total
FROM `'._DB_PREFIX_.'sale_product` sp
LEFT JOIN '._DB_PREFIX_.'sales s ON (sp.id_sale = s.id_sale)
WHERE DATE_FORMAT(s.`date`, "%m-%Y") BETWEEN "'.$monthFrom.'" AND "'.$monthTo.'"';
GROUP BY DATE_FORMAT(s.date, "%M-%Y")

Categories